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)? _______________________________________________ Haskell-Cafe mailing list [email protected] http://www.haskell.org/mailman/listinfo/haskell-cafe
