monads: Add 'mwhen' and 'munless'.

* guix/monads.scm (mbegin): Add special '%current-monad' syntactic
  keyword.
  (mwhen, munless): New macros.
This commit is contained in:
Ludovic Courtès 2014-12-02 10:11:11 +01:00
parent cc7fa5929c
commit 21caa6deeb
2 changed files with 31 additions and 1 deletions

View file

@ -46,6 +46,8 @@
(eval . (put 'syntax-parameterize 'scheme-indent-function 1)) (eval . (put 'syntax-parameterize 'scheme-indent-function 1))
(eval . (put 'with-monad 'scheme-indent-function 1)) (eval . (put 'with-monad 'scheme-indent-function 1))
(eval . (put 'mbegin 'scheme-indent-function 1)) (eval . (put 'mbegin 'scheme-indent-function 1))
(eval . (put 'mwhen 'scheme-indent-function 1))
(eval . (put 'munless 'scheme-indent-function 1))
(eval . (put 'mlet* 'scheme-indent-function 2)) (eval . (put 'mlet* 'scheme-indent-function 2))
(eval . (put 'mlet 'scheme-indent-function 2)) (eval . (put 'mlet 'scheme-indent-function 2))
(eval . (put 'run-with-store 'scheme-indent-function 1)) (eval . (put 'run-with-store 'scheme-indent-function 1))

View file

@ -39,6 +39,8 @@ (define-module (guix monads)
mlet mlet
mlet* mlet*
mbegin mbegin
mwhen
munless
lift1 lift2 lift3 lift4 lift5 lift6 lift7 lift lift1 lift2 lift3 lift4 lift5 lift6 lift7 lift
listm listm
foldm foldm
@ -173,9 +175,15 @@ (define-syntax mlet
body ...))))))) body ...)))))))
(define-syntax mbegin (define-syntax mbegin
(syntax-rules () (syntax-rules (%current-monad)
"Bind the given monadic expressions in sequence, returning the result of "Bind the given monadic expressions in sequence, returning the result of
the last one." the last one."
((_ %current-monad mexp)
mexp)
((_ %current-monad mexp rest ...)
(>>= mexp
(lambda (unused-value)
(mbegin %current-monad rest ...))))
((_ monad mexp) ((_ monad mexp)
(with-monad monad (with-monad monad
mexp)) mexp))
@ -185,6 +193,26 @@ (define-syntax mbegin
(lambda (unused-value) (lambda (unused-value)
(mbegin monad rest ...))))))) (mbegin monad rest ...)))))))
(define-syntax mwhen
(syntax-rules ()
"When CONDITION is true, evaluate EXP0..EXP* as in an 'mbegin'. When
CONDITION is false, return *unspecified* in the current monad."
((_ condition exp0 exp* ...)
(if condition
(mbegin %current-monad
exp0 exp* ...)
(return *unspecified*)))))
(define-syntax munless
(syntax-rules ()
"When CONDITION is false, evaluate EXP0..EXP* as in an 'mbegin'. When
CONDITION is true, return *unspecified* in the current monad."
((_ condition exp0 exp* ...)
(if condition
(return *unspecified*)
(mbegin %current-monad
exp0 exp* ...)))))
(define-syntax define-lift (define-syntax define-lift
(syntax-rules () (syntax-rules ()
((_ liftn (args ...)) ((_ liftn (args ...))