summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2014-10-08 23:35:08 +0200
committerLudovic Courtès <ludo@gnu.org>2014-10-08 23:35:20 +0200
commit405a9d4ec9806993a6453f0dfba78fc65d5e7993 (patch)
tree83096b186be61f0a0daca3b808ab2aeb58bfb352
parent2e1bafb03438757c7cc34c16230b00623507ff84 (diff)
downloadpatches-405a9d4ec9806993a6453f0dfba78fc65d5e7993.tar
patches-405a9d4ec9806993a6453f0dfba78fc65d5e7993.tar.gz
monads: Add 'mbegin'.
* guix/monads.scm (mbegin): New macro. * tests/monads.scm ("mbegin"): New test. * doc/guix.texi (The Store Monad): Document it.
-rw-r--r--.dir-locals.el1
-rw-r--r--doc/guix.texi9
-rw-r--r--guix/monads.scm14
-rw-r--r--tests/monads.scm17
4 files changed, 40 insertions, 1 deletions
diff --git a/.dir-locals.el b/.dir-locals.el
index edc964123f..6cd55e7788 100644
--- a/.dir-locals.el
+++ b/.dir-locals.el
@@ -38,6 +38,7 @@
(eval . (put 'syntax-parameterize 'scheme-indent-function 1))
(eval . (put 'with-monad 'scheme-indent-function 1))
+ (eval . (put 'mbegin 'scheme-indent-function 1))
(eval . (put 'mlet* 'scheme-indent-function 2))
(eval . (put 'mlet 'scheme-indent-function 2))
(eval . (put 'run-with-store 'scheme-indent-function 1))
diff --git a/doc/guix.texi b/doc/guix.texi
index ed2b81ba33..c9760f5f60 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -2061,6 +2061,15 @@ Bind the variables @var{var} to the monadic values @var{mval} in
(@pxref{Local Bindings,,, guile, GNU Guile Reference Manual}).
@end deffn
+@deffn {Scheme System} mbegin @var{monad} @var{mexp} ...
+Bind @var{mexp} and the following monadic expressions in sequence,
+returning the result of the last expression.
+
+This is akin to @code{mlet}, except that the return values of the
+monadic expressions are ignored. In that sense, it is analogous to
+@code{begin}, but applied to monadic expressions.
+@end deffn
+
The interface to the store monad provided by @code{(guix monads)} is as
follows.
diff --git a/guix/monads.scm b/guix/monads.scm
index 2ab3fb94f0..d9580a7f8e 100644
--- a/guix/monads.scm
+++ b/guix/monads.scm
@@ -38,6 +38,7 @@
with-monad
mlet
mlet*
+ mbegin
lift1 lift2 lift3 lift4 lift5 lift6 lift7 lift
listm
foldm
@@ -171,6 +172,19 @@ form is (VAR -> VAL), bind VAR to the non-monadic value VAL in the same way as
(let ((var temp) ...)
body ...)))))))
+(define-syntax mbegin
+ (syntax-rules ()
+ "Bind the given monadic expressions in sequence, returning the result of
+the last one."
+ ((_ monad mexp)
+ (with-monad monad
+ mexp))
+ ((_ monad mexp rest ...)
+ (with-monad monad
+ (>>= mexp
+ (lambda (unused-value)
+ (mbegin monad rest ...)))))))
+
(define-syntax define-lift
(syntax-rules ()
((_ liftn (args ...))
diff --git a/tests/monads.scm b/tests/monads.scm
index 5514c8386c..6e3dd00f72 100644
--- a/tests/monads.scm
+++ b/tests/monads.scm
@@ -32,7 +32,7 @@
#:use-module (srfi srfi-26)
#:use-module (srfi srfi-64))
-;; Test the (guix store) module.
+;; Test the (guix monads) module.
(define %store
(open-connection-for-tests))
@@ -99,6 +99,21 @@
%monads
%monad-run))
+(test-assert "mbegin"
+ (every (lambda (monad run)
+ (with-monad monad
+ (let* ((been-there? #f)
+ (number (mbegin monad
+ (return 1)
+ (begin
+ (set! been-there? #t)
+ (return 2))
+ (return 3))))
+ (and (= (run number) 3)
+ been-there?))))
+ %monads
+ %monad-run))
+
(test-assert "mlet* + text-file + package-file"
(run-with-store %store
(mlet* %store-monad ((guile (package-file %bootstrap-guile "bin/guile"))