Talk:Haskell/Understanding monads

Archives

 * /Nuclear waste/ - archives from before the great rewrite (see especially the last thread) 2007-08-03

Rewrite of the page?
A complete rewrite of the page seems to have been initiated today. I think it's a shame, since the original version with the nuclear waste metaphor was by far the best tutorial I've ever seen. Since I couldn't find any discussion of this huge change anywhere, I've reverted Apfelmus's changes. --Nattfodd 14:00, 3 August 2007 (UTC)


 * Thanks, Natt. The discussion (confusingly) took place on /Nuclear waste/.  The problem with the original version is that it gives only a superficial understanding of monads and doesn't help the reader to really "get" the point (I say this because I am guilty for most of it).  Reverting your revert.  Apfelmus is a well trusted member of this community.  He understands the strengths of the original version and will likely find a way to preserve them whilst overcoming the major shortcomings :-) -- Kowey 14:07, 3 August 2007 (UTC)


 * No the metaphor is great! I watched the WIP page, like, "monad is a triplet of (M, return, >==) where they satisfy laws 1, 2 and 3" etc etc. I couldn't get it after staring at it for ten seconds. I'm generally opposed to the "Yankee textbook" style where everything is explained thrice really down-bowing like to a retard monkey, but the other extreme only works if you've got a live instructor. This book's value as a self-study material benefits hugely from such witty and well-written metaphors as in this article! --Sigmundur (talk) 18:01, 2 October 2008 (UTC)


 * Well, staring at a definition usually doesn't work, the intention was that the reader reads on :-).
 * The dilemma is the following: if there's no clear definition, some people complain that "monad" is just a buzzword (like "cloud computing" etc.). If there's a metaphor, some people complain that don't see the wood for the metaphorical trees anymore, especially if the metaphor is stretched beyond its limits. If it starts with explaining that  is an "action that calculates a value  " (that's how the SPJ's "awkward squad" paper does it and which worked for me), some people complain that this is too abstract either. Hm, now what to do? :-)
 * -- apfe&lambda;mus 09:05, 3 October 2008 (UTC)

Section "Motivation"
Thanks for taking up on this somewhat stalled text.

A motivating example is a good idea, but it can easily become a demotivating example if it's too complicated/confusing. I think the core idea of  is reasonably clear, but the cursory remarks, for instance about   and "openness" are too much.

Moreover, I'd certainly avoid saying that monads are "relatively difficult", for they are not, or rather, should not be by virtue of this text.

-- apfe&lambda;mus 08:53, 4 August 2009 (UTC)

Topics TODO
  Explain monadic parser combinators! But in another chapter.  The basic triad "rock, scissors, paper" err, "reader, writer, state" is best introduced in another chapter, maybe entitled "A Zoo of Monads". Reader must include the famous function  also known as  !  The  is too cute to not elaborate it further to probabilistic functional programming. The Monty Hall problem can be solved with that. Key: the implementation can be changed, it effectively becomes the Set-Monad then. Extension:  and backtracking.  Exceptions are a nice way to explain monads, too. See also. </li> </ul>

Links

 * Brent Yorgey - "The monad tutorial fallacy". Highly relevant! The assertion is that everyone has to discover the abstraction and a suitable metaphor himself, by working through examples. Presenting a metaphor upfront is no use.
 * Ertugrul Söylemez' monad tutorial
 * Henk-Jan van Tuyl - A tour of the Haskell monad functions

Obsolete notes
Move the italic inline notes here when no longer necessary.

What is a monad?
''We're bold and present the exact definition of "monad". This should (hopefully) prevent common confusion about the definition and remove the buzzword status. Of course, this paragraph has to be really short since it doesn't explain why I should care about monads at all or what the intuition behind bind and return is.''

Stateful Computations
''Example state monads, i.e. particular state types. One of them is to be treated before/in parallel to. The others may be useful for exercises!'' <ul><li>''random numbers. Drawbacks: $$\gg$$ is meaningless, using an infinite list of random numbers is a better abstraction. Highlights: the state is more an implementation detail than of individual importance, this makes explanation easier!'' </li><li>''name-supply. Task: label all leaves in a tree from 1 to n.'' </li><li>Data.Map for depth first search in a graph. </li><li>''SOE, chapter 19: interactive robot language. Nice example monad to program in. But not a good example for implementation.'' </li></ul> <i> Of course, the problem with an example is that we need to explain the example use case before plunging into. But it's probably worth it. Huh, it turns out that we even have to explain the  pattern for threading state. Seems that random numbers are easiest to explain. </i>

Monad zoo
Just to point out that shapr's girlfriend had some amusing illustrations of monads... might be useful for an eventual Monad Zoo chapter -- Kowey 16:07, 7 August 2007 (UTC)


 * Marvelous, there more amusement, the better ;-) I intend the "Monad Zoo" chapter to take the role of Haskell/Advanced monads. -- apfe&lambda;mus 17:11, 7 August 2007 (UTC)

Need Images?
I could draw up some preliminary figures/images if you'd like. I'm not familiar with Haskell, but if I can contribute while I learn... why not? :)





These images correspond to the first monad example, a random number generator.


 * Oh, thank you! I had something along the lines of the diagrams in the awkward squad paper in mind, though, i.e. something like [[Image:MonadState sumTwoDice.png]]. This demonstrates how  is composed of two successive  . Image:monad_state_random2.jpg somehow misses this point :-) I'm not sure wether rectangular boxes are the way to go though, your colorful circles make me thinking.
 * -- apfe&lambda;mus 19:01, 21 February 2008 (UTC)

Changes from 20 April 2010
A helpful contributor has made some changes, recorded here: Revision 1761620 compared to 1733846.

Unfortunately, I think they tend to confuse matters more than they enlighten and I chose to undo them. They are modeled on the Monads as Containers tutorial, but this approach is very different from the one taken here and they don't mix very well. How about putting them in an extra section?

I do agree that /  viewpoint should be explained somewhere as well.

-- apfe&lambda;mus 11:30, 21 April 2010 (UTC)

Prelude and
We should show a way to hide  and the other monad functions while importing the Prelude.

-- apfe&lambda;mus 06:55, 23 April 2009 (UTC)

How to combine Actions with a function?
For example,I write a function to get the nth fibonacci number. fib 0 = 1 fib 1 = 1 fib n = fib (n-1) + (fib (n-2)) And it takes long time to get the 1000th number.So I want to show the progress.When it get the 100th,200th,300th,... number,the console print 1,2,3,....How to do this? Must I modify my function or I can make a wrapper of it.


 * For debugging, you can use to show intermediate results.
 * In general, you have to change your function to  something.

fib n = print n >> case n of  0 -> return 1 1 -> return 1 n -> liftM2 (+) (fib (n-1)) (fib (n-2))
 * Note that your algorithm needs exponential time! I estimate that  will take  around $$10^{190}$$ years. For better algorithms, see also The Fibonacci sequence on the Haskell Wiki.
 * The Haskell Cafe Mailinglist is probably better for asking Haskell questions than the wikibook.
 * -- apfe&lambda;mus 13:49, 5 August 2007 (UTC)

Nomenclature: use of f as a monadic value
In the introductory set of three equations, and throughout, you use x for a value, and f,g,h for either monadic values, or functions. I would use either x, m or a for a monadic variable. i.e.

f >>= return == f

becomes:

a >>= return == a

f is strongly associated with function names. -- Neil Mitchell/ndm


 * Good point! How do others do it? SPJ in "Tackling the awkwards squad" says

return x >>= f = f x m >>= return = m m1 >>= (λx.m2 >>= (λy.m3)) = (m1 >>= (λx.m2)) >>= (λy.m3)

with the condition that x is not free in m3. Wadler in "Monads for functional programming" essentially says

return a >>= λb.n = n[a/b] m >>= λa.return a = m m >>= (λa.n >>= λb.o)) = (m >>= λa.n) >>= λb.o

but uses  and   instead of   and.

In my own Haskell code, I always use m for monadic values and g,h for functions that return monadic values. That means

return x >>= g = g x m >>= return = m (m >>= g) >>= h = m >>= (\x -> g x >>= h)

Hm, do I really do that? Oh, dear. I guess just using m for monadic values and f,g for the functions is probably best. Hm, but the other versions of the associative law are more associative.
 * -- apfe&lambda;mus 09:19, 6 August 2007 (UTC)

Trouble with currying
I'm not confident enough in my Haskell knowledge to outright correct this, but something looks wrong to me. In the section Threading the State with bind, the definition of >> is:

(>>) :: (Seed -> (a,Seed)) -> (Seed -> (b,Seed)) -> (Seed -> (b,Seed)) (>>) f g seed0 = let (result1, seed1) = f seed0 (result2, seed2) = g seed1 in (result2, seed2)

It looks like the type signature and definition disagree. In particular, the signature indicates that >> produces a function. However, the definition seems to produce a pair (b, Seed). On the other hand, this might just be Haskell magic. --Bytecrafter 22:00, 11 November 2007 (UTC)


 * Even more strangely, >> takes three parameters instead of two... Don't worry, this is just Currying :-) For instance, we may say that (+) is a function that takes one parameter and returns a function, i.e.  and   but we may also think of (+) as taking two parameters.
 * The definition of >> is similar. Hm, maybe it's better to write
 * but the  spans multiple lines, so I'm not sure whether this helps.
 * -- apfe&lambda;mus 12:00, 12 November 2007 (UTC)
 * -- apfe&lambda;mus 12:00, 12 November 2007 (UTC)


 * OK, I wasn't sure if that was going on or not. I've only ever seen currying in the invocation of functions, not the definition.  Does that imply that the following type signatures are equivalent?

(>>) :: (Seed -> (a,Seed)) -> (Seed -> (b,Seed)) -> (Seed -> (b,Seed)) (>>) :: (Seed -> (a,Seed)) -> (Seed -> (b,Seed)) -> Seed -> (b,Seed)
 * Yes, exactly. -> is right-associative, i.e.  is parsed as.
 * I'm sorry to spam up this discussion page (clearly these questions belong on the currying page), but let me share my impressions. As a reader, I came to this page out of order.  I know a bit about functional programming, but I only know enough Haskell to be able to read it.  I can't really write it.  However, I was very interested to learn more about Monads, since the little that I did know led me to believe that they were magical and cool.
 * No problem, I mean, "out of order" is to the default on the Internet :-) so the/any article should facilitate that. Hm, having an explicit dependency graph for the chapters would be ideal.
 * I had expected to see that (>>) would return a function, and was a bit surprised to see that the definition didn't seem to match the type signature. There are probably other readers in similar situations.  It might make sense to get the type signature and the function definition to agree.
 * I changed some definitions, better that way?
 * To counterbalance my criticism, let me also say that this is the single best Monad discussion that I have seen so far. I appreciate the work that people have put into it, and my comments are only intended to help make the article even better!  --Bytecrafter 01:28, 13 November 2007 (UTC)
 * Yes, thanks for your comments! Moreover, there doesn't seem to be an explanation of currying in the wikibook (!? I suppose it's intended to be in Haskell/Higher-order_functions_and_Currying, hm even a bit late for my taste), your remarks brought to light that it's rather absent.
 * -- apfe&lambda;mus 09:37, 14 November 2007 (UTC)

"What is a monad" missing something?
A monad is a "thing" that can plug into the monadic plumbing system.

''Think of an internet enabled appliance. What does that mean? It means a "thing" that can plug into the internet. But the internet is basically just a giant router. The functionality all depends on what's plugged in. If no one ever showed you a web browser or a chat client, then you would probably have no idea what the internet is.''

Nevertheless, we can define what a monad is, without giving even the slightest hint of what a monad is good for.


 * Moved Oddron's addition here because IMHO they don't fit. But they're not without point, what do you want to express, Oddron? What bugs you about the current version?
 * The section intentionally does not give an explananation of what monads are good for in order to avoid making it sound like a buzzword.
 * Strictly speaking, there is no "monadic pumbling system". I don't like the internet example, though it does have the good point that there are many very different monads, i.e. that "monad" itself is a rather bare-bones concept.
 * -- apfe&lambda;mus 07:47, 6 June 2008 (UTC)

Confused by type definition given for Map?
map :: a -> b -> M a -> M b I'm new to Wikibooks, and haven't the foggiest about monads yet. Appologies if my understanding is wrong but if it's intuitively like map then shouldn't the only difference should be in what the function operates on and what's returned. ie more like map :: (a -> b) -> M a -> M b

-- Steve10345book (talk) 00:11, 21 April 2010 (UTC)


 * Yes, you're right.
 * Note that what you were reading were recent edits that I think confuse matters too much; I've relocated them to another section. The text will be different now. Wikibook - where the text changes while you're reading it. ;-)
 * -- apfe&lambda;mus 12:21, 21 April 2010 (UTC)
 * Thanks for clearing that up. Wasn't sure if it were a deliberate error or not. It's quite reassuraning that I have learnt something from previous sections of this wikibook. I've not got a maths, or programming background and feel a good educational book should attempt to build on familar ideas to explain differences with new ideas. As such I quite liked the map analogy, but haven't got the subtle difference with aplication. Keep up the good work, and I'll attempt to help out where I can.
 * Steve10345book (talk) 07:42, 22 April 2010 (UTC)


 * Ah, but who knows what the reader is familiar with. ;-) You probably want to use additional books for learning Haskell anyway; I can recommend Learn you a Haskell or Graham Hutton's book Programming in Haskell.
 * -- apfe&lambda;mus 11:23, 23 April 2010 (UTC)

Subsection "What is a Monad?"
In the Right unit law, is m a generic type variable or is it of the monad type M?

Similarly with the  Associativity  law. GPhilip (talk) 12:50, 7 July 2008 (UTC)


 * In both cases,  denotes a value of type   (for some type  ). -- apfe&lambda;mus 21:24, 7 July 2008 (UTC)

Recent expansion of section "Definition"
Blaisorblade, I don't agree that your elaboration on the definition is a good idea. My intention was to keep it extremely short and jump right into the example. I think that someone who doesn't know what a monad is yet won't understand the additional remarks, but still waste a lot of time trying to understand them. He is better served by doing the example first and inferring his own intuition from that.

-- apfe&lambda;mus 07:35, 7 August 2010 (UTC)


 * I'm in total agreement with Apfelmus: the "cut to the chase" approach of the older versions of this chapter was a key factor in its effectiveness (not that my subjective POV counts much, but I speak as someone who actually learnt monads as a complete newbie starting from this article). Right now I am strongly inclined to remove the whole "Why I need monads" foreword, as well as most of the additions to the introduction.Duplode (discuss • contribs) 22:39, 1 April 2012 (UTC)


 * So I went ahead and performed the "surgery". Last revision before the trimming: --Duplode (discuss • contribs) 04:31, 15 April 2012 (UTC)

Category Theory
Hey, I changed the intro to the Category Theory section so as not to imply that the join/map/return presentation of monads is exactly the categorical definition. It's not. For one, Haskell is not Category Theory; it just has some operations based on concepts from C.T. For another, Haskell monads actually correspond to so-called "strong monads" in C.T.  The difference is that, in a strong monad's version of bind, extra information is passed into the function passed to bind. This corresponds exactly to the existing scope in Haskell. In Haskell, a function passed to bind is closed over the existing scope, and so has access to all variables already in scope, as well as the bound variable. In a categorical strong monad, this is done with a product; in Haskell, it is done with closures and scope. (I am mkehrt on WP; I don't exist on WB).

Broken Link
Link to Haskell/Understanding monads/Error is broken as it seems that section no longer exists. This should be replaced with an appropriate link, or removed.

imperative stuff is confusing me
This section:

… this isn't making sense to me. let x = foo in bar ? This is too abstract. Is the x being used? Is it ever usable in the future? Or is this just a throwaway thing? And the last part "of the imperative language" is baffling. What is this imperative language we are referring to? Should it be "of *an* imperative language" ?? None of this is very clear or helpful in my case. Backfromquadrangle (discuss • contribs) 18:22, 2 May 2014 (UTC)
 * Under this interpretation, the bind operator  is simply a function version of the semicolon. Just like a :  expression can be written as a function application,
 * let x = foo in bar     corresponds to      (\x -> bar) foo
 * an assignment and semicolon can be written as the bind operator:
 * x <- foo;  bar     corresponds to      foo >>= (\x -> bar)
 * The  function lifts a value   to a full-fledged statement   of the imperative language.
 * x <- foo;  bar     corresponds to      foo >>= (\x -> bar)
 * The  function lifts a value   to a full-fledged statement   of the imperative language.
 * The  function lifts a value   to a full-fledged statement   of the imperative language.
 * The  function lifts a value   to a full-fledged statement   of the imperative language.


 * The let examples were, in a precise sense, pseudo-Haskell.  wasn't actually a Haskell expression, but a placeholder for an expression which might use   (or not, though if it didn't the   would be superfluous). It could be , or  . I agree it was unnecessarily abstract, so I made the example concrete.


 * As for the passage about, it is really "the imperative language"; that is, the imperative language implemented by the monad   you happen to choose. I changed the sentence to make that explicit. Does it help?--Duplode (discuss • contribs) 02:33, 3 May 2014 (UTC)

Add amazing link?
Yet Another Monad Tutorial is by far the best thorough explanation out there, skipping all the nonsense. I think we should either provide a "more reading" link to it or otherwise use it as a model for improving the Wikibook. Backfromquadrangle (discuss • contribs) 16:30, 9 June 2014 (UTC)


 * It is a good tutorial indeed. The approach is also quite close to what we are trying to do here, except that the pace is much slower, and the exposition more meticulous. Do you think the link would fit better here or with the broader set of tutorials linked from the front page?--Duplode (discuss • contribs) 03:19, 10 June 2014 (UTC)

Handling the Applicative-Monad proposal
I have just made the absolute minimal changes needed for this chapter to comply with GHC 7.10 and the AMP. No attempt is made to discuss  here, or even to link to the (freshly updated) ../Applicative functors chapter. I see that as possibly more than a temporary solution - IMO it is not necessary to discuss applicatives before monads, and that there are pros and cons with either approach. In any case, a curious reader at this point of the book should be able to do a quick visit to the chapter about applicatives and understand at least the first three sections, so that she sees what the passing mention was about. Duplode (discuss • contribs) 10:43, 4 July 2015 (UTC)


 * A follow-up: given that this chapter is preceded by a prologue whose main goal is introducing, the text was adjusted accordingly. The main change is that there are now several references to  , as we do not have to pretend it doesn't exist any longer. The structure remains essentially the same. Note that the caveat about not asking readers to instantiate   on their own yet still applies, as doing so would call for a deeper discussion of   than the Prologue is able to provide. --Duplode (discuss • contribs) 04:44, 10 October 2016 (UTC)