Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Understand Haskell Monads through Macros (common-lisp.net)
45 points by tomdtpink on Dec 12, 2010 | hide | past | favorite | 2 comments


Here's one small macro that I think addresses most of the pain:

    ;; (with f ((var val)...) body...)
    ;;==> (f (lambda (var...) body...) val...)
    (defmacro with (f bindings &body body)
      `(funcall ,f (lambda ,(mapcar #'car bindings) ,@body)
                ,@(mapcar #'cadr bindings)))
You use it like this, assuming you have monad functions UNIT and BIND:

    (with bind ((v1 e1))
      (with bind ((v2 e2))
        (unit (+ v1 v2))))
If you need multiple types of monads, and you can't just give them each different function names, then use generic functions for UNIT and BIND (with two differences from Haskell: Haskell's 'return' is generic in the resulting monad type, not the argument type, and the type's resolved at compile time). When I've done this in Scheme I only needed one kind of monad, so I didn't bother.

WITH can be handy for other things; I already had it lying around when the occasion came up to use a monad in Scheme.

Oleg's written about another approach using delimited continuations.


I think the reason that a lot of people have trouble trying to understand monads is that they don't really understand type classes. If you understand type classes, then the definition of a monad is pretty obvious, although you might have to think about it for a little while to see how it relates to computation and how to use it. (Another issue is that people are introduced to the Maybe type in the context of monads and latch onto the mistaken idea that the Maybe type is the Maybe monad... just look at all the blog posts about it.)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: