Cats Api Documentation

Version: 2.2.0

cats.core

Category Theory abstractions for Clojure

->=

macro

(->= expr & forms)

Like ->, but with monadic binding instead of pure application. A mnemonic for the name is a pun on >>=, the monadic bind operator, and clojure’s regular arrow macros.

You can think of it as generalizing the some-> thread macro to all Monads instead of just Maybe.

Alternatively, if you think of the regular thread macro as sugar for let:

(-> :a b (c (other args)) d) => (let [res (b :a) res (c res (other args)) res (d res)] res)

Then ->= is sugar for cats.core/mlet:

(->= m-a b (c (other args)) d) (mlet [res m-a res (c res (other args)) res (d res)] (return res))

Note that extra args in this context are assumed pure, and will be evaluated along with the function itself; this also matches the behavior of some-> wrt extra args.

Threading through pure functions is somewhat awkward, but can be done:

(->= m-a monadic-fn (-> pure-fn other-pure-fn m/return) other-monadic-fn)

->>=

macro

(->>= expr & forms)

Like ->>, but with monadic binding instead of pure application. See cats.labs.sugar/->= for more in-depth discussion.

<$>

A Haskell-style fmap alias.

<*>

A Haskell-style fapply alias.

<=<

(<=< mg mf x)

Right-to-left composition of monads. Same as >=> with its first two arguments flipped.

=<<

(=<< f mv)

Same as the two argument version of >>= but with the arguments flipped.

>=>

(>=> mf mg x)

Left-to-right composition of monads.

>>

(>> mv mv')(>> mv mv' & mvs)

Perform a Haskell-style left-associative bind, ignoring the values produced by the monadic computations.

>>=

(>>= mv f)(>>= mv f & fs)

Perform a Haskell-style left-associative bind.

Let’s see it in action:

(>>= (just 1) (comp just inc) (comp just inc))
;; => #<Just [3]>

alet

macro

(alet bindings & body)

Applicative composition macro similar to Clojure’s let. This macro facilitates composition of applicative computations using fmap and fapply and evaluating applicative values in parallel.

Let’s see an example to understand how it works. This code uses fmap for executing computations inside an applicative context:

(fmap (fn [a] (inc a)) (just 1)) ;=> #<Just [2]>

Now see how this code can be made clearer by using the alet macro:

(alet [a (just 1)] (inc a)) ;=> #<Just [2]>

Let’s look at a more complex example, imagine we have dependencies between applicative values:

(join (fapply (fmap (fn [a] (fn [b] (fmap (fn [c] (inc c)) (just (+ a b))))) (just 1)) (just 2))) ;=> #<Just [4]>

This is greatly simplified using alet:

(alet [a (just 1) b (just 2) c (just (+ a b))] (inc c)) ;=> #<Just [4]>

The intent of the code is much clearer and evaluates a and b at the same time, then proceeds to evaluate c when all the values it depends on are available. This evaluation strategy is specially helpful for asynchronous applicatives.

ap

macro

(ap f & args)

Apply a pure function to applicative arguments, e.g.

(ap + (just 1) (just 2) (just 3)) ;; => #<Just [6]> (ap str [“hi” “lo”] [“bye” “woah” “hey”]) ;; => [“hibye” “hiwoah” “hihey” “lobye” “lowoah” “lohey”]

ap is essentially sugar for (apply fapply (pure f) args), but for the common case where you have a pure, uncurried, possibly variadic function.

ap actually desugars in alet form:

(macroexpand-1 `(ap + (just 1) (just2))) ;; => (alet [a1 (just 1) a2 (just 2)] (+ a1 a2))

That way, variadic functions Just Work, without needing to specify an arity separately.

If you’re familiar with Haskell, this is closest to writing “in Applicative style”: you can straightforwardly convert pure function application to effectful application by with some light syntax (<$> and <*> in case of Haskell, and ap here).

See the original Applicative paper for more inspiration: http://staff.city.ac.uk/~ross/papers/Applicative.pdf

ap->

macro

(ap-> x & forms)

Thread like ->, within an applicative idiom.

Compare:

(macroexpand-1 `(-> a b c (d e f))) => (d (c (b a) e f)

with:

(macroexpand-1 `(ap-> a b c (d e f)) => (ap d (ap c (ap b a) e f))

ap->>

macro

(ap->> x & forms)

Thread like ->>, within an applicative idiom. See cats.labs.sugar/ap-> for more in-depth discussion.

as->=

macro

(as->= expr name & forms)

Like as->, but with monadic binding instead of pure application. See cats.labs.sugar/->= for more in-depth discussion.

as-ap->

macro

(as-ap-> expr name & forms)

Thread like as->, within an applicative idiom. See cats.labs.sugar/ap-> for more in-depth discussion.

bimap

(bimap f g)(bimap f g bv)

Map over both arguments at the same time.

Given functions f and g and a value wrapped in a bifunctor bv, apply f to a first argument or g to a second argument.

(bimap dec inc (either/right 1)
;; => #<Right 2>

(bimap dec inc (either/left 1)
;; => #<Left 0>

bind

(bind mv f)

Given a monadic value mv and a function f, apply f to the unwrapped value of mv.

(bind (either/right 1) (fn [v]
                         (return (inc v))))
;; => #<Right [2]>

For convenience, you may prefer to use the mlet macro, which provides a beautiful, let-like syntax for composing operations with the bind function.

curry

macro

(curry f)(curry n f)

Given either a fixed arity function or an arity and a function, return another which is curried.

With inferred arity (function must have one fixed arity):

(defn add2 [x y] (+ x y))
(def cadd2 (curry add2))

((cadd2 1) 3)
;; => 4

(cadd2 1 3)
;; => 4

With given arity:

(def c+ (curry 3 +))

((c+ 1 2) 3)
;; => 6

((((c+) 1) 2) 3)
;; => 6

curry*

macro

(curry* args body)

curry-lift-m

macro

(curry-lift-m n f)

Composition of curry and lift-m

extract

(extract v)

Generic function to unwrap/extract the inner value of a container.

fapply

(fapply af & avs)

Given a function wrapped in a monadic context af, and a value wrapped in a monadic context av, apply the unwrapped function to the unwrapped value and return the result, wrapped in the same context as av.

This function is variadic, so it can be used like a Haskell-style left-associative fapply.

filter

(filter p mv)

Apply a predicate to a value in a MonadZero instance, returning the identity element when the predicate does not hold.

Otherwise, return the instance unchanged.

(require '[cats.monad.maybe :as maybe])
(require '[cats.core :as m])

(m/filter (partial < 2) (maybe/just 3))
;=> <Just [3]>

(m/filter (partial < 4) (maybe/just 3))
;=> <Nothing>

fmap

(fmap f)(fmap f fv)

Apply a function f to the value wrapped in functor fv, preserving the context type.

foldl

(foldl f z xs)

Perform a left-associative fold on the data structure.

foldm

(foldm f z xs)(foldm ctx f z xs)

Given an optional monadic context, a function that takes two non-monadic arguments and returns a value inside the given monadic context, an initial value, and a collection of values, perform a left-associative fold.

(require '[cats.context :as ctx]
         '[cats.core :as m]
         '[cats.monad.maybe :as maybe])

(defn m-div [x y]
  (if (zero? y)
    (maybe/nothing)
    (maybe/just (/ x y))))

(m/foldm m-div 1 [1 2 3])
(m/foldm maybe/context m-div 1 [1 2 3])
;; => #<Just 1/6>

(m/foldm maybe/context m-div 1 [1 0 3])
;; => #<Nothing>

(foldm m-div 1 [])
;; => Exception

(m/foldm maybe/context m-div 1 [])
(ctx/with-context maybe/context
  (foldm m-div 1 []))
;; => #<Just 1>

foldr

(foldr f z xs)

Perform a right-associative fold on the data structure.

forseq

(forseq vs mf)

Same as mapseq but with the arguments flipped.

Let’s see a little example:

(m/forseq [2 3] maybe/just)
;; => <Just [[2 3]]>

Yet an other example that fails:

(m/forseq [1 2]
          (fn [v]
            (if (odd? v)
              (maybe/just v)
              (maybe/nothing))))
;; => <Nothing>

join

(join mv)

Remove one level of monadic structure. This is the same as (bind mv identity).

left-map

(left-map f)(left-map f bv)

Map covariantly over the first argument.

Given a function f and a value wrapped in a bifunctor bv, apply f to the first argument, if present, otherwise leave bv unchanged.

(left-map dec (either/right 1)
;; => #<Right 1>

(left-map dec (either/left 1)
;; => #<Left 0>

lift-a

macro

(lift-a f)(lift-a n f)

Lift a function with a given fixed arity to an applicative context.

(def app+ (lift-a 2 +))

(app+ (maybe/just 1) (maybe/just 2)) ;; =>

(app+ (maybe/just 1) (maybe/nothing)) ;; =>

(app+ [0 2 4] [1 2]) ;; => [1 2 3 4 5 6]

lift-m

macro

(lift-m f)(lift-m n f)

Lift a function with a given fixed arity to a monadic context.

(def monad+ (lift-m 2 +))

(monad+ (maybe/just 1) (maybe/just 2)) ;; => <Just [3]>

(monad+ (maybe/just 1) (maybe/nothing)) ;; =>

(monad+ [0 2 4] [1 2]) ;; => [1 2 3 4 5 6]

mappend

(mappend & svs)

mapseq

(mapseq mf coll)

Given a function mf that takes a value and puts it into a monadic context, and a collection, map mf over the collection, calling sequence on the results.

(require '[cats.context :as ctx]
         '[cats.monad.maybe :as maybe]
         '[cats.core :as m])

(m/mapseq maybe/just [2 3])
;=> <Just [[2 3]]>

(m/mapseq (fn [v]
            (if (odd? v)
              (maybe/just v)
              (maybe/nothing)))
          [1 2])
;; => #<Nothing>

(ctx/with-context maybe/context
  (mapseq #(maybe/just (* % 2)) []))
;; => #<Just [()]>

mempty

(mempty)(mempty ctx)

mlet

macro

(mlet bindings & body)

Monad composition macro that works like Clojure’s let. This facilitates much easier composition of monadic computations.

Let’s see an example to understand how it works. This code uses bind to compose a few operations:

(bind (just 1)
      (fn [a]
        (bind (just (inc a))
                (fn [b]
                  (return (* b 2))))))
;=> #<Just [4]>

Now see how this code can be made clearer by using the mlet macro:

(mlet [a (just 1)
       b (just (inc a))]
  (return (* b 2)))
;=> #<Just [4]>

mplus

(mplus & mvs)

mzero

(mzero)(mzero ctx)

pure

(pure v)(pure ctx v)

Given any value v, return it wrapped in the default/effect-free context.

This is a multi-arity function that with arity pure/1 uses the dynamic scope to resolve the current context. With pure/2, you can force a specific context value.

Example:

(with-context either/context
  (pure 1))
;; => #<Right [1]>

(pure either/context 1)
;; => #<Right [1]>

return

(return v)(return ctx v)

This is a monad version of pure and works identically to it.

right-map

(right-map g)(right-map g bv)

Map covariantly over the second argument.

Given a function g and a value wrapped in a bifunctor bv, apply g to the second argument, if present, otherwise leave bv unchanged.

(right-map inc (either/right 1)
;; => #<Right 2>

(right-map inc (either/left 1)
;; => #<Left 1>

sequence

(sequence mvs)

Given a collection of monadic values, collect their values in a seq returned in the monadic context.

(require '[cats.context :as ctx]
         '[cats.monad.maybe :as maybe]
         '[cats.core :as m])

(m/sequence [(maybe/just 2) (maybe/just 3)])
;; => #<Just [[2, 3]]>

(m/sequence [(maybe/nothing) (maybe/just 3)])
;; => #<Nothing>

(ctx/with-context maybe/context
  (m/sequence []))
;; => #<Just [()]>

traverse

(traverse f tv)(traverse ctx f tv)

Map each element of a structure to an action, evaluate these actions from left to right, and collect the results.

(defn inc-if-even
  [n]
  (if (even? n)
    (maybe/just (inc n))
    (maybe/nothing)))

(ctx/with-context maybe/context
  (m/traverse inc-if-even [2 4]))
;; => #<Just [3 4]>

unless

macro

(unless b mv)(unless ctx b mv)

Given an expression and a monadic value, if the expression is not logical true, return the monadic value. Otherwise, return nil in a monadic context.

when

macro

(when b mv)(when ctx b mv)

Given an expression and a monadic value, if the expression is logical true, return the monadic value. Otherwise, return nil in a monadic context.