[Haskell-cafe] Teaching Monads
Derek Elkins
derek.a.elkins at gmail.com
Sat Jun 7 12:54:18 EDT 2008
On Sat, 2008-06-07 at 00:05 -0400, Ronald Guida wrote:
> Monads in Haskell are a topic that I, like most beginners, find
> difficult and "mind-twisting". Now that I think I understand monads,
> they seem to be very simple; I've read that this is a common
> experience.
>
> So I wonder, what would it take to help beginners catch on with a
> minimum of fuss or frustration? The plethora of monad tutorials out
> there is clear evidence that plenty of others have wondered the same
> thing.
>
> What made monads "click" for me is when I understood the following
> things:
>
> 1. When monads are being used, closures are almost always involved.
>
> 2. These closures naturally arise when desugaring do-syntax.
>
> do x1 <- m1 m1 >>= (\x1 ->
> x2 <- m2 m2 >>= (\x2 -> [Eq1]
> x3 <- m3 m3 >>= (\x3 ->
> return (f x1 x2 x3) return (f x1 x2 x3))))
>
> 3. These closures are extremely similar to the closures that arise
> when desugaring let-syntax.
>
> let x1 = f1 in f1 -$ (\x1 -> Where:
> let x2 = f2 in f2 -$ (\x2 -> (-$) :: a -> (a -> b) -> b
> let x3 = f3 in f3 -$ (\x3 -> x -$ f = f x
> f x1 x2 x3 f x1 x2 x3)))
>
> 4. While I can think of a monad as a fancy container that holds an
> element of type "t", it might be more accurate to think of a monad
> as a container that merely displays the type "t" as a label for its
> contents. The container might hold one object of type "t", or it
> might hold several. It might not be holding any at all. Perhaps
> the container /never/ holds an object of type "t", but instead it
> holds a set of instructions to produce such an object.
> (e.g. Reader, State).
>
> Naturally, it's hard to illustrate nested closures, higher-order
> functions, and objects that aren't really there. It's easy to
> illustrate a sequential scheme where a single "thing" passes through a
> series of operations, while some related data travels in parallel.
>
> m1 >>= f1 >>= f2 >>= f3 [Eq2]
>
> In any case, the extreme similarity between desugared "do" and
> desugared "let" leads me to think of the concepts of a manual
> plumbing system and a monadic plumbing system.
>
> Basically, a manual plumbing system is what I have if I'm threading
> information down through a series of nested function calls in a
> certain stereotypical way. A monadic plumbing system is what I get
> when I introduce the appropriate monad to encapsulate my threading.
>
> In fact, if I look at Wadler [*], there are three examples of an
> evaluator that use what I'm calling "manual plumbing". In section
> 2.5, the operations required of a monad (return, bind) pretty much
> just drop right out. Wadler even points out the similarity between
> "bind" and "let".
>
> Now that I finally "get it", I feel that the Wadler paper, section 2.5
> in particular, is probably a better introduction than many of the
> monad tutorials out there. Moreover, I feel that for /some/ of
> the tutorials out there, they spend too much time and too many
> illustrations explaining things like [Eq2], and then they quickly
> present do-notation and gloss over [Eq1].
>
> For me, I found that that the concepts of "manual plumbing" and
> "monadic plumbing" were key to actually grasping the Wadler paper and
> understanding what monads are. In particular, I feel that these two
> concepts might be a way to help other beginners catch on as well.
>
> OK, so before I attempt to write a monad tutorial based on "manual
> plumbing" and "monadic plumbing", I would like to know, does anyone
> else think this is a good idea?
Why should I recommend a beginner to this tutorial rather than one of
the dozens of others online or, better yet, to Wadler's papers directly
(which is what I do)?
More information about the Haskell-Cafe
mailing list