Monad in Scheme (2)

ukaiさんが、書いて下さった。なるほど...素晴らしいっす!という事で、もう少し詰めてみることにする。Monad in Scheme (1)での僕の書き方は少し曖昧だったので、モナドが満たすべき3つの法則(モナド則)を満たすように書き直してみた。とはいっても、ukaiさんのを少しいじくっただけなので、基本的なアイデアは同じ。ちなみに、Haskellでの\x -> f xは、Schemeでの(lambda (x) (f x))で有る。これを満たすようにモナド関数return, >>=を書いてみた。

  • The monad laws
    • (return x) >>= f == f x
    • m >>= return == m
    • (m >>= f) >>= g == m >>= (\x -> f x >>= g)
; Monad Function
(define (>>= val args)
  (let ((m ((car args) val))
        (rest (cdr args)))
    (if (null? rest)
        m
        (apply m rest))))

(define (return val)
  (lambda (op . args)
    (op val args)))

; Util
(define (monad-val monad)
  (monad (lambda (val . args) val)))

; User Func                                                                                                                                    
(define (inc n) (return (+ n 1)))
(define (inc2 n) (return (+ n 2)))

; The monad laws                                                                                                                                       
; 1. ((return x) >>= f) == (f x)                                                                                                               
(print (monad-val ((return 1) >>= inc)))
(print (monad-val (inc 1)))

; 2. (m >>= return) == m                                                                                                                   
(print (monad-val ((return 1) >>= return)))
(print (monad-val (return 1)))

; 3. ((m >>= f) >>= g) == (m >>= (lambda (x) ((f x) >>= g)))                                                                                   
(print (monad-val (((return 1) >>= inc) >>= inc2)))
(print (monad-val ((return 1) >>= (lambda (x) ((inc x) >>= inc2)))))