diff options
author | Ludovic Courtès <ludo@gnu.org> | 2014-07-12 17:16:36 +0200 |
---|---|---|
committer | Ludovic Courtès <ludo@gnu.org> | 2014-07-12 23:17:53 +0200 |
commit | f62435e2868f5db15cc2f31300630c8ec873dd58 (patch) | |
tree | 4c48f36fafd1c02b5d65fb92fd257e3bd0c78dc0 | |
parent | c2150d9acece1dcaf54b3183254db4f83a992523 (diff) | |
download | guix-f62435e2868f5db15cc2f31300630c8ec873dd58.tar.gz |
monads: Fix 'mapm' so that effects happen from left to right.
* guix/monads.scm (mapm): Don't reverse LST, so that items are processed from left to right. Bind the result of 'foldm' and reverse it. * tests/monads.scm ("sequence"): Change 'frob' so it performs its side effect within an 'mlet' body. Adjust call accordingly.
-rw-r--r-- | guix/monads.scm | 16 | ||||
-rw-r--r-- | tests/monads.scm | 14 |
2 files changed, 17 insertions, 13 deletions
diff --git a/guix/monads.scm b/guix/monads.scm index ec2b7f8b3b..c2c6f1a03d 100644 --- a/guix/monads.scm +++ b/guix/monads.scm @@ -209,13 +209,15 @@ monadic value seeded by INIT." (define (mapm monad mproc lst) "Map MPROC over LST, a list of monadic values in MONAD, and return a monadic -list." - (foldm monad - (lambda (item result) - (mlet monad ((item (mproc item))) - (return (cons item result)))) - '() - (reverse lst))) +list. LST items are bound from left to right, so effects in MONAD are known +to happen in that order." + (mlet monad ((result (foldm monad + (lambda (item result) + (mlet monad ((item (mproc item))) + (return (cons item result)))) + '() + lst))) + (return (reverse result)))) (define-inlinable (sequence monad lst) "Turn the list of monadic values LST into a monadic list of values, by diff --git a/tests/monads.scm b/tests/monads.scm index 82f4b9989c..ac19d33f93 100644 --- a/tests/monads.scm +++ b/tests/monads.scm @@ -166,14 +166,16 @@ (let* ((input (iota 100)) (order '())) (define (frob i) - ;; The side effect here is used to keep track of the order in - ;; which monadic values are bound. - (set! order (cons i order)) - i) + (mlet monad ((foo (return 'foo))) + ;; The side effect here is used to keep track of the order in + ;; which monadic values are bound. Perform the side effect + ;; within a '>>=' so that it is performed when the return + ;; value is actually bound. + (set! order (cons i order)) + (return i))) (and (equal? input - (run (sequence monad - (map (lift1 frob monad) input)))) + (run (sequence monad (map frob input)))) ;; Make sure this is from left to right. (equal? order (reverse input))))) |