(define-module (control monad procedures) #:use-module (oop goops) #:use-module (srfi srfi-1) ; concatenate! #:export (>> >>= return)) (define-generic return) (define-method (return (a )) identity) (define-method (return (a )) list) (define-generic >>=) (define-method (>>= (a ) (proc )) (proc a)) (define-method (>>= (this ) proc) '()) (define-method (>>= (this ) (proc )) (concatenate! (map proc this))) (define-generic >>) (define-method (>> (a ) (b )) (>>= a (lambda args b))) (define-method (>> (a ) (b )) '()) (define-method (>> (a ) (b )) '()) (define-method (>> (a ) (b )) '()) (define-method (>> (a ) (b )) (concatenate! (map (const b) a))) ;; bind :: Monad m => m a -> (a -> m b) -> m b ;; return :: Monad m => a -> m a ;; map :: Functor f => (a -> b) -> f a -> f b