2014-07-09 22:28:06 -04:00
|
|
|
(defmacro monad (name)
|
2014-07-09 22:37:16 -04:00
|
|
|
(case name
|
|
|
|
;; Provide the state monad in terms of the state transformer
|
|
|
|
(''state `(transformer 'state 'identity))
|
|
|
|
(_
|
2015-05-21 19:14:39 -05:00
|
|
|
`(list_to_atom (lists:flatten `("calrissian-"
|
|
|
|
,(atom_to_list ,name)
|
|
|
|
"-monad"))))))
|
2014-07-09 22:28:06 -04:00
|
|
|
|
|
|
|
(defmacro transformer (name inner-monad)
|
2015-05-21 19:14:39 -05:00
|
|
|
`(tuple (list_to_atom (lists:flatten `("calrissian-"
|
|
|
|
,(atom_to_list ,name)
|
|
|
|
"-transformer")))
|
2014-07-09 22:28:06 -04:00
|
|
|
(monad ,inner-monad)))
|
|
|
|
|
2014-04-25 01:11:04 -04:00
|
|
|
(defmacro do-m args
|
2014-04-24 15:33:28 -04:00
|
|
|
(let ((monad (car args))
|
|
|
|
(statements (cdr args)))
|
2014-07-09 21:19:14 -04:00
|
|
|
(calrissian-monad:do-transform monad statements)))
|
2014-04-24 15:33:28 -04:00
|
|
|
|
|
|
|
(defmacro >>= (monad m f)
|
2014-05-13 19:30:46 -04:00
|
|
|
`(call ,monad '>>= ,m ,f))
|
2014-04-24 15:33:28 -04:00
|
|
|
|
|
|
|
(defmacro >> (monad m1 m2)
|
2014-05-13 19:30:46 -04:00
|
|
|
`(call ,monad '>>= ,m1 (lambda (_) , m2)))
|
2014-04-24 15:33:28 -04:00
|
|
|
|
|
|
|
(defmacro return (monad expr)
|
2014-05-13 19:30:46 -04:00
|
|
|
`(call ,monad 'return ,expr))
|
2014-04-25 01:06:19 -04:00
|
|
|
|
2014-04-25 01:27:13 -04:00
|
|
|
(defmacro fail (monad expr)
|
2014-05-13 19:30:46 -04:00
|
|
|
`(call ,monad 'fail ,expr))
|
2014-04-25 01:27:13 -04:00
|
|
|
|
2014-04-25 01:06:19 -04:00
|
|
|
(defmacro sequence (monad list)
|
2015-05-21 19:14:39 -05:00
|
|
|
`(lists:foldr
|
2014-04-25 01:06:19 -04:00
|
|
|
(lambda (m acc) (mcons ,monad m acc))
|
|
|
|
(return ,monad [])
|
|
|
|
,list))
|
|
|
|
|
|
|
|
(defmacro mcons (monad m mlist)
|
2014-04-25 01:11:04 -04:00
|
|
|
`(do-m ,monad
|
|
|
|
(x <- ,m)
|
|
|
|
(rest <- ,mlist)
|
|
|
|
(return ,monad (cons x rest))))
|