moar is a small monad library I wrote for Clojure. It brings Haskell-style bind, >>=, fmap and friends to Clojure, along with a handful of common monads and monad transformers.

The core idea is built on Clojure protocols. A monadic value like (just 4) implements a MonadInstance protocol that points back to its monad implementation (here maybe/monad), and that implementation provides Monad and, optionally, MonadPlus. So bind, >>=, fmap and >> work like their Haskell counterparts, but dispatch on the monad implementation at runtime based on their monadic argument.

Haskell’s return is the odd one out: Clojure can’t dispatch on the return type at compile time, so in moar you name the monad explicitly with wrap:

(>>= (wrap maybe/monad 2)
     (fn [x] (just (inc x)))
     (fn [x] nothing)
     (fn [x] (just (inc x))))
;;=> #<Nothing moar.monads.maybe.Nothing@72ca7ea3>

The library ships with identity, maybe, result, sequence, set, state and continuation monads, plus an mlet form for do-style binding. Transformers let you stack them, and the README has an example that combines continuation and state with callcc to build a small loop. There is also an infer namespace that can derive Functor and Applicative implementations from a Monad one, so a new monad only needs wrap and bind to get fmap for free.

The design goals I set out were: no magic, easy to extend, good error messages, and an implementation that fits Clojure’s dynamic nature rather than fighting it.

Source on GitHub: Jell/moar