Write yourself some Haskell for great good..

Some monad examples for haskell98-tutorial.pdf

; The ideas are quite simple:
; * make a list of actions to perform:
;   (define as (list (delay (display 1)) (delay (display 2)) (delay (display 3))))
; * reduce them one by one, in order, to a value, usually IO ()
;   (force (force (force (sequence_ as))))

; to create a list of promises we need a lazy map from Haskell
(define (lazy-map f xs)
  (if (null? xs)
      (cons (delay (f (car xs)))
	    (lazy-map f (cdr xs)))))

; lazy foldr, like in Haskell
(define (lazy-foldr f b xs)
  (if (null? xs)
      (delay (f (car xs)
		(lazy-foldr f b (cdr xs))))))

; run some Haskell
(define (run e)
  (and (promise? e)
       (run (force e))))

; (>>)           :: Monad m => m a -> m b -> m b
(define (>> a b)                  ; shift
    (force a)

; return         :: Monad m => a -> m a
(define (ret e)                   ; wrap
  (delay e))

; some syntactic sugar
(define (do! a b)
  (>> a b))

; sequence_       :: [IO ()] -> IO () 
(define (sequence_ as)
  (if (null? as)
      (ret '())
      (do! (car as)
	   (delay (sequence_ (cdr as))))))

; test
(define as (list (delay (display 1)) (delay (display 2)) (delay (display 3))))
(force (force (force (force (sequence_ as)))))

;sequence_        :: Monad m => [m a] -> m () 
(define (sequence_ as)			; reduce to ()              
  (lazy-foldr >> (ret '()) as))

; mapM_           :: Monad m => (a -> m b) -> [a] -> m ()
(define (mapM_ f as)
  (sequence_ (lazy-map f as)))

; some currying
(define (curry f)
  (lambda (x) 
    (f x)))

; print :: String -> IO ()
(define (print s)
  (sequence_ (lazy-map (curry display) s)))

; test
(run (print '(a b c d)))

; test
(run (mapM_ (curry display) '(a b c d)))
Last modified 7 years ago Last modified on Jul 30, 2013, 7:48:40 AM
Note: See TracWiki for help on using the wiki.