mirror of
https://github.com/correl/calrissian.git
synced 2024-11-27 11:09:58 +00:00
Generalized monad interface
This commit is contained in:
parent
ecd20c50ec
commit
c0441ca1e7
5 changed files with 59 additions and 38 deletions
13
include/monads.lfe
Normal file
13
include/monads.lfe
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
(defmacro do args
|
||||||
|
(let ((monad (car args))
|
||||||
|
(statements (cdr args)))
|
||||||
|
(monad:do-transform monad statements)))
|
||||||
|
|
||||||
|
(defmacro >>= (monad m f)
|
||||||
|
`(: ,monad >>= ,m ,f))
|
||||||
|
|
||||||
|
(defmacro >> (monad m1 m2)
|
||||||
|
`(: ,monad >>= ,m1 (lambda (_) ,m2)))
|
||||||
|
|
||||||
|
(defmacro return (monad expr)
|
||||||
|
`(: ,monad return ,expr))
|
14
src/maybe-monad.lfe
Normal file
14
src/maybe-monad.lfe
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
(defmodule maybe-monad
|
||||||
|
(behaviour monad)
|
||||||
|
(export (>>= 2)
|
||||||
|
(return 1)
|
||||||
|
(fail 1)))
|
||||||
|
|
||||||
|
(defun >>=
|
||||||
|
(('nothing f)
|
||||||
|
'nothing)
|
||||||
|
(((tuple 'just x) f)
|
||||||
|
(funcall f x)))
|
||||||
|
|
||||||
|
(defun return (x) (tuple 'just x))
|
||||||
|
(defun fail (_) 'nothing)
|
|
@ -1,25 +0,0 @@
|
||||||
(defmodule maybe
|
|
||||||
(export all))
|
|
||||||
|
|
||||||
(defun my-adder (x y)
|
|
||||||
(+ x (+ y 1)))
|
|
||||||
|
|
||||||
(defun >>=
|
|
||||||
(('nothing f)
|
|
||||||
'nothing)
|
|
||||||
(((tuple 'just x) f)
|
|
||||||
(funcall f x)))
|
|
||||||
|
|
||||||
(defun >> (a b)
|
|
||||||
(>>= a (lambda (_) b)))
|
|
||||||
|
|
||||||
(defun return (x) (tuple 'just x))
|
|
||||||
(defun fail (_) 'nothing)
|
|
||||||
|
|
||||||
(defun do-statement
|
|
||||||
(((cons h '())) h)
|
|
||||||
(((cons (list f '<- m) t)) (list ': 'maybe '>>=
|
|
||||||
m
|
|
||||||
(list 'lambda (list f) (do-statement t))))
|
|
||||||
(((cons h t)) (list ': 'maybe '>> h (do-statement t)))
|
|
||||||
)
|
|
17
src/monad.lfe
Normal file
17
src/monad.lfe
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
(defmodule monad
|
||||||
|
(export (behaviour-info 1)
|
||||||
|
(do-transform 2)))
|
||||||
|
|
||||||
|
(defun behaviour-info
|
||||||
|
(('callbacks) (list #(>>= 2)
|
||||||
|
#(return 1)
|
||||||
|
#(fail 1)))
|
||||||
|
((_) 'undefined))
|
||||||
|
|
||||||
|
(defun do-transform
|
||||||
|
((monad (cons h '())) h)
|
||||||
|
((monad (cons (list f '<- m) t)) (list ': monad '>>=
|
||||||
|
m
|
||||||
|
(list 'lambda (list f) (do-transform monad t))))
|
||||||
|
((monad (cons h t)) (list '>> monad h (do-transform monad t)))
|
||||||
|
)
|
|
@ -1,4 +1,4 @@
|
||||||
(defmodule unit-maybe-tests
|
(defmodule unit-maybe-monad-tests
|
||||||
(export all)
|
(export all)
|
||||||
(import
|
(import
|
||||||
(from lfeunit-util
|
(from lfeunit-util
|
||||||
|
@ -6,27 +6,27 @@
|
||||||
(check-wrong-assert-exception 2))))
|
(check-wrong-assert-exception 2))))
|
||||||
|
|
||||||
(include-lib "deps/lfeunit/include/lfeunit-macros.lfe")
|
(include-lib "deps/lfeunit/include/lfeunit-macros.lfe")
|
||||||
(include-lib "include/maybe.lfe")
|
(include-lib "include/monads.lfe")
|
||||||
|
|
||||||
(deftest bind-nothing
|
(deftest bind-nothing
|
||||||
(is-equal 'nothing
|
(is-equal 'nothing
|
||||||
(maybe:>>= 'nothing
|
(>>= maybe-monad 'nothing
|
||||||
(lambda (x) (+ 5 x)))))
|
(lambda (x) (+ 5 x)))))
|
||||||
|
|
||||||
(deftest bind-nothing-error
|
(deftest bind-nothing-error
|
||||||
(is-equal 'nothing
|
(is-equal 'nothing
|
||||||
(maybe:>>= 'nothing
|
(>>= maybe-monad 'nothing
|
||||||
(lambda (_) (error 'bad-func)))))
|
(lambda (_) (error 'bad-func)))))
|
||||||
|
|
||||||
(deftest bind-five
|
(deftest bind-five
|
||||||
(is-equal 10
|
(is-equal 10
|
||||||
(maybe:>>= (tuple 'just 5)
|
(>>= maybe-monad (tuple 'just 5)
|
||||||
(lambda (x) (+ 5 x)))))
|
(lambda (x) (+ 5 x)))))
|
||||||
|
|
||||||
(deftest bind-fold
|
(deftest bind-fold
|
||||||
(is-equal #(just 3)
|
(is-equal #(just 3)
|
||||||
(let ((minc (lambda (x) (maybe:return (+ 1 x))))
|
(let ((minc (lambda (x) (return maybe-monad (+ 1 x))))
|
||||||
(bind (lambda (f m) (maybe:>>= m f))))
|
(bind (lambda (f m) (>>= maybe-monad m f))))
|
||||||
(lists:foldr bind
|
(lists:foldr bind
|
||||||
#(just 0)
|
#(just 0)
|
||||||
(list minc
|
(list minc
|
||||||
|
@ -35,15 +35,17 @@
|
||||||
|
|
||||||
(deftest >>
|
(deftest >>
|
||||||
(is-equal #(just 3)
|
(is-equal #(just 3)
|
||||||
(maybe:>> #(just 5) #(just 3))))
|
(>> maybe-monad #(just 5) #(just 3))))
|
||||||
|
|
||||||
(deftest do-bindings
|
(deftest do-bindings
|
||||||
(is-equal #(just 3)
|
(is-equal #(just 3)
|
||||||
(do (a <- #(just 1))
|
(do maybe-monad
|
||||||
(b <- #(just 2))
|
(a <- #(just 1))
|
||||||
(maybe:return (+ a b)))))
|
(b <- #(just 2))
|
||||||
|
(return maybe-monad (+ a b)))))
|
||||||
|
|
||||||
(deftest do-nobindings
|
(deftest do-nobindings
|
||||||
(is-equal #(just 3)
|
(is-equal #(just 3)
|
||||||
(do #(just 5)
|
(do maybe-monad
|
||||||
#(just 3))))
|
#(just 5)
|
||||||
|
#(just 3))))
|
Loading…
Reference in a new issue