Skip to content
Snippets Groups Projects
Commit f62435e2 authored by Ludovic Courtès's avatar Ludovic Courtès
Browse files

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.
parent c2150d9a
No related branches found
No related tags found
No related merge requests found
...@@ -209,13 +209,15 @@ (define (foldm monad mproc init lst) ...@@ -209,13 +209,15 @@ (define (foldm monad mproc init lst)
(define (mapm monad mproc lst) (define (mapm monad mproc lst)
"Map MPROC over LST, a list of monadic values in MONAD, and return a monadic "Map MPROC over LST, a list of monadic values in MONAD, and return a monadic
list." list. LST items are bound from left to right, so effects in MONAD are known
(foldm monad to happen in that order."
(lambda (item result) (mlet monad ((result (foldm monad
(mlet monad ((item (mproc item))) (lambda (item result)
(return (cons item result)))) (mlet monad ((item (mproc item)))
'() (return (cons item result))))
(reverse lst))) '()
lst)))
(return (reverse result))))
(define-inlinable (sequence monad lst) (define-inlinable (sequence monad lst)
"Turn the list of monadic values LST into a monadic list of values, by "Turn the list of monadic values LST into a monadic list of values, by
......
...@@ -166,14 +166,16 @@ (define derivation-expression ...@@ -166,14 +166,16 @@ (define derivation-expression
(let* ((input (iota 100)) (let* ((input (iota 100))
(order '())) (order '()))
(define (frob i) (define (frob i)
;; The side effect here is used to keep track of the order in (mlet monad ((foo (return 'foo)))
;; which monadic values are bound. ;; The side effect here is used to keep track of the order in
(set! order (cons i order)) ;; which monadic values are bound. Perform the side effect
i) ;; within a '>>=' so that it is performed when the return
;; value is actually bound.
(set! order (cons i order))
(return i)))
(and (equal? input (and (equal? input
(run (sequence monad (run (sequence monad (map frob input))))
(map (lift1 frob monad) input))))
;; Make sure this is from left to right. ;; Make sure this is from left to right.
(equal? order (reverse input))))) (equal? order (reverse input)))))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment