Haskell style do-notation in Chez Scheme
Auxiliary keyword for syntax monad.
Mimics Haskell's do-notation.
(monad flat-map e e* ...)flat-mapneeds to be a valid flat map implementation- the last form in
e e*...must be a valid monadic value emay be a valid monadic valueemay be a monadic binding form(<- x mx)wherexis a bound variablemxmust be a valid monadic value
emay be a non-binding form(let binding binding* ...)corresponds to(let (binding binding* ...) (monad flat-map e* ...))(let* binding binding* ...)corresponds to(let* (binding binding* ...) (monad flat-map e* ...))(letrec binding binding* ...)corresponds to(letrec (binding binding* ...) (monad flat-map e* ...))(let-values binding binding* ...)corresponds to(let-values (binding binding* ...) (monad flat-map e* ...))(let*-values binding binding* ...)corresponds to(let*-values (binding binding* ...) (monad flat-map e* ...))
emay be a named non-binding form(let name binding binding* ...)corresponds to(let name (binding binding* ...) (monad flat-map e* ...))
(define none '#(none))
(define (option-flat-map f mx)
(if (eq? mx none) mx (f mx)))(define (list-flat-map f xs)
(apply append (map f xs)))(define (identity-flat-map f x) (f x))(monad option-flat-map 42)
; 42(monad list-flat-map (list 1 2 3))
; (1 2 3)(monad option-flat-map
(<- x 5)
(<- y 4)
(+ x y))
; 9(monad option-flat-map
(<- x 5)
(<- y none)
(+ x y))
; #(none)(monad list-flat-map
(<- x (list 1 2 3))
(<- y (list 4 5))
(list (cons x y)))
; ([1 . 4] [1 . 5] [2 . 4] [2 . 5] [3 . 4] [3 . 5])(monad option-flat-map
(let [x 7]
[y none])
x)
; 7(monad option-flat-map
(let [x 7]
[y none])
y
x)
; #(none)(monad identity-flat-map
(let loop [i 1] [acc 0])
(if (<= i 10)
(loop (add1 i) (+ acc i))
acc))
; 55