diff --git a/include/monad-tests.lfe b/include/monad-tests.lfe new file mode 100644 index 0000000..e3f1321 --- /dev/null +++ b/include/monad-tests.lfe @@ -0,0 +1,44 @@ +(defmacro test-monad-laws (monad) + `(progn + (deftest monad-left-identity + (let ((a 3) + (f (lambda (n) (return ,monad (* 3 n))))) + (is-equal (>>= ,monad (return ,monad a) f) + (funcall f a)))) + + (deftest monad-right-identity + (let ((m (return ,monad 3))) + (is-equal (>>= ,monad m (lambda (m') (return ,monad m'))) + m))) + + (deftest monad-associativity + (let ((m (return ,monad 3)) + (f (lambda (n) (return ,monad (* 3 n)))) + (g (lambda (n) (return ,monad (+ 5 n))))) + (is-equal (>>= ,monad (>>= ,monad m f) g) + (>>= ,monad m (lambda (x) (>>= ,monad (funcall f x) g)))))) + + (deftest monad-do-left-identity + (let ((a 3) + (f (lambda (n) (return ,monad (* 3 n))))) + (is-equal (do ,monad (a' <- (return ,monad a)) + (funcall f a')) + (do ,monad (funcall f a))))) + + (deftest monad-do-right-identity + (let ((m (return ,monad 3))) + (is-equal (do ,monad (x <- m) + (return ,monad x)) + (do ,monad m)))) + + (deftest monad-do-associativity + (let ((m (return ,monad 3)) + (f (lambda (n) (return ,monad (* 3 n)))) + (g (lambda (n) (return ,monad (+ 5 n))))) + (is-equal (do ,monad (y <- (do ,monad (x <- m) + (funcall f x))) + (funcall g y)) + (do ,monad (x <- m) + (do ,monad (y <- (funcall f x)) + (funcall g y)))))) + )) diff --git a/test/unit/unit-maybe-monad-tests.lfe b/test/unit/unit-maybe-monad-tests.lfe index 38c5a24..7f5ac96 100644 --- a/test/unit/unit-maybe-monad-tests.lfe +++ b/test/unit/unit-maybe-monad-tests.lfe @@ -7,18 +7,21 @@ (include-lib "deps/lfeunit/include/lfeunit-macros.lfe") (include-lib "include/monads.lfe") +(include-lib "include/monad-tests.lfe") -(deftest bind-nothing +(test-monad-laws maybe-monad) + +(deftest bind-short-circuit-value (is-equal 'nothing (>>= maybe-monad 'nothing (lambda (x) (+ 5 x))))) -(deftest bind-nothing-error +(deftest bind-short-circuit-error (is-equal 'nothing (>>= maybe-monad 'nothing (lambda (_) (error 'bad-func))))) -(deftest bind-five +(deftest bind (is-equal 10 (>>= maybe-monad (tuple 'just 5) (lambda (x) (+ 5 x))))) @@ -48,4 +51,4 @@ (is-equal #(just 3) (do maybe-monad #(just 5) - #(just 3)))) \ No newline at end of file + #(just 3))))