MOOOOAR!!1!
-- The Internet
A monad library made for Clojure. No macros needed.
Quick example:
(ns moar.example
(:require [moar.core :refer :all]
[moar.protocols :refer :all]
[moar.monads.sequence :as sequence]
[moar.monads.continuation :as continuation]
[moar.monads.state :as state]
[moar.monads.maybe :as maybe :refer [just nothing]]))
(wrap maybe/monad :tobias)
;;=> #<Just@74de792d: :tobias>
(bind (just 2) #(wrap maybe/monad (inc %)))
;;=> #<Just@1e8c0586: 3>
@(just :x)
;;=> :x
(>>= (wrap maybe/monad 2)
(fn [x] (just (inc x)))
(fn [x] nothing)
(fn [x] (just (inc x))))
;;=> #<Nothing moar.monads.maybe.Nothing@72ca7ea3>
(fmap inc (just 2))
;;=> #<Just@590d3235: 3>
(= (just 2) (just 2))
;;=> true
(= (just 2) (just 3))
;;=> false
;; Monad transformers!
;; Continuation + State!
(let [monad (continuation/monad-t state/monad)
run continuation/run
return (partial wrap monad)
callcc (partial continuation/callcc monad)
modify (comp (partial lift monad)
(partial state/modify state/monad))
pull (comp (partial lift monad)
(partial state/pull state/monad))
my-loop (>> (callcc (fn [cont]
(modify assoc :next
(partial cont nil))))
(modify update-in [:count] inc)
(mlet [n (pull :count)
next (pull :next)]
(modify update-in [:log] conj n)
(if (< n 5)
(next)
(>> (modify dissoc :next)
(return :done)))))]
((run my-loop) {:count 0 :log []}))
;;=> #moar.monads.state.Pair{:state {:count 5, :log [1 2 3 4 5]}, :result :done}
- No magic
- Easily extensible
- Intelligent error messages
- Support all major monads
- Support for major monad transformers
- Adapt implementation to the dynamic nature of Clojure
val
: values (a)fun
: functions (a -> b)m-val
: monadic values (MonadInstance m => m a)m-fun
: monadic functions (a -> m a)m-impl
: implementation of a monad (Monad, MonadPlus)t-impl
: implementation of a monad transformer
-
a monadic value like
(just 4)
implements theMonadInstance
protocol, which points to a monad implementation (maybe/monad
in that case) that implements theMonad
(and potentially theMonadPlus
) protocol. -
return
in haskell becomeswrap monad
inmoar
. Since we can't dispatch on the return type at compile time in Clojure, we do an explicit dispatch on the monad implementation at runtime.We chose
wrap
instead ofreturn
to avoid confusion to newcomers. -
bind
,>>=
,fmap
and>>
behave like their haskell counterpart, except that they dispatch the monad implementation at runtime based on their monadic argument.
- Cleanup monad transformers (a bit rough right now)
- Better pretty printing
lift
(not yet drafted)- More monad and monad transformers implementations
Copyright © 2014 FIXME
Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.