Skip to content

Instantly share code, notes, and snippets.

Created September 1, 2010 20:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/0508e6219da9ee0adc01 to your computer and use it in GitHub Desktop.
Save anonymous/0508e6219da9ee0adc01 to your computer and use it in GitHub Desktop.
(define-module define-monad
:doc "Defines vars with the definitions provided for '>>= and 'return
(and 'zero and 'plus when provided) and creates namespace-local
versions of the generic monadic functions. By default all of the
monadic functions in combinatrix.monad are defined.
If 'syntax is provided a monad-comprehension macro with the given
name will also be defined. The examples in combinatrix.monad.*
probably offer the clearest demonstration of usage."
:required [>>= return]
:optional [zero plus syntax include exclude rename]
(require 'combinatrix.util)
(combinatrix.util/definitions
;; this is possibly taking the haskell syntax theme too far
;; ... but its so tidy ...
>> ma mb := (>>= ma (fn [_] mb))
>> ma mb & mbs := (>> ma (apply >> mb mbs))
lift f := (fn [mv] (>>= mv (fn [x] (return (f x)))))
lift2 f := (fn [m n] (>>= m (fn [x]
(>>= n (fn [y]
(return (f x y)))))))
fmap f mv := (>>= mv (fn [x] (return (f x))))
m-map f xs := (m-seq (map f xs))
m-seq mvs :=
(letfn [(m-seq* [xs acc]
(if-let [[y & ys] (seq xs)]
(>>= y (fn [z] (m-seq* ys (conj acc z))))
(return (seq acc))))]
(m-seq* mvs []))
chain steps :=
(letfn [(link [expr step]
(fn [v] (>>= (expr v) step)))]
(reduce link return steps))
until p f x :=
(if (p x)
(return x)
(>>= (f x)
(fn [y] (>>= (until p f y)
(fn [z] (return z)))))))
(when syntax
(eval (do-monad-template syntax))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment