
I hate monads. I love 90% of Haskell. The functional stuff is beautiful, easy to understand, crystal clear, elegant, etc. But I'm having a mighty hard time getting my head around monads. Consider the following explanation of a monad: "A monad is represented as a type constructor (call it m), a function that builds values of that type (a -> m a), and a function that combines values of that type with computations that produce values of that type to produce a new computation for values of that type". 1) I know what a type is, but not a "type constructor". I don't normally think of an Int or even a complex type as being "constructed" except in the sense of OOP which I know is not what the author means. 2) Just *read* the paragraph... "a type constructor, a function that builds value of that type, and a function that combines values of that type with computations that produce values of that type to produce a computation of values of that type" Ugh.... Can anyone recommend a simple and clear explanation of monads? You can assume that I know basic math and basic Haskell syntax. So, for example, "a -> b" is much more clear than "a function that takes input of one type and has an output of a different type". Any help would be appreciated. Daniel.

"Daniel" == Daniel Carrera
writes:
Daniel> Can anyone recommend a simple and clear explanation of Daniel> monads? You can assume that I know basic math and basic Daniel> Haskell syntax. So, for example, "a -> b" is much more Daniel> clear than "a function that takes input of one type and Daniel> has an output of a different type". This is excellent: http://ertes.de/articles/monads.html -- Colin Adams Preston Lancashire

Colin Paul Adams wrote:
This is excellent:
Thanks! I'll start reading that page immediately. Cheers, Daniel.

Daniel Carrera wrote:
Colin Paul Adams wrote:
This is excellent:
Thanks! I'll start reading that page immediately.
I noticed that this tutorial points to the following blog: http://byorgey.wordpress.com/2009/01/12/abstraction-intuition-and-the-monad-... Wow! The author of this blog has nailed it. Trust me, I know, I was a math teacher for years (a *good* teacher, based on student reviews). The author of this blog is exactly right about why most tutorials about abstract concepts are no help (and why so many math teachers are bad). Now I'll go on to read the tutorial, encouraged that the author probably knows how to teach. Cheers, Daniel.

On Wed, Apr 22, 2009 at 01:01:46PM +0200, Daniel Carrera wrote:
Daniel Carrera wrote:
Colin Paul Adams wrote:
This is excellent:
http://ertes.de/articles/monads.html Thanks! I'll start reading that page immediately.
I noticed that this tutorial points to the following blog:
http://byorgey.wordpress.com/2009/01/12/abstraction-intuition-and-the-monad-...
Wow! The author of this blog has nailed it. Trust me, I know, I was a math teacher for years (a *good* teacher, based on student reviews). The author of this blog is exactly right about why most tutorials about abstract concepts are no help (and why so many math teachers are bad).
Thanks! =) You may also be interested in taking a look at the Typeclassopedia, in issue 13 of the Monad.Reader. http://haskell.org/haskellwiki/The_Monad.Reader -Brent

On 22 Apr 2009, at 12:26, Colin Paul Adams wrote:
"Daniel" == Daniel Carrera
writes: Daniel> Can anyone recommend a simple and clear explanation of Daniel> monads? You can assume that I know basic math and basic Daniel> Haskell syntax. So, for example, "a -> b" is much more Daniel> clear than "a function that takes input of one type and Daniel> has an output of a different type".
This is excellent:
Hopefully this will help too - monads are made rather too much of, just build up slowly to them rather than diving into them first – they're not the be all and end all of classes. http://noordering.wordpress.com/2009/03/31/how-you-shouldnt-use-monad/ Bob

This is excellent:
Wow. That really is a great tutorial! Suddenly the world becomes clear... Definitely gets my vote as must read material. Cheers, Sam

Sam Martin wrote:
This is excellent:
Wow. That really is a great tutorial! Suddenly the world becomes clear...
Definitely gets my vote as must read material.
+1 I was very impressed too. And I am not easy to impress when it comes to documentation. I plan to read it a second time to solidify some of the ideas, but on my first reading my understanding of Monads increased by leaps and bounds. Ertugrul deserves to be commended, and this tutorial should be made more prominent on haskell.org. Daniel.

"Daniel" == Daniel Carrera
writes:
Daniel> Sam Martin wrote: >>> This is excellent: >>> >>> http://ertes.de/articles/monads.html >> >> Wow. That really is a great tutorial! Suddenly the world >> becomes clear... >> >> Definitely gets my vote as must read material. Daniel> +1 Daniel> I was very impressed too. And I am not easy to impress Daniel> when it comes to documentation. I plan to read it a second Daniel> time to solidify some of the ideas, but on my first Daniel> reading my understanding of Monads increased by leaps and Daniel> bounds. Daniel> Ertugrul deserves to be commended, and this tutorial Daniel> should be made more prominent on haskell.org. I think so. I've read VERY MANY tutorials on monads, and they were all confusing - except this one. -- Colin Adams Preston Lancashire

Hello people,
thanks for all your positive comments about my tutorial, both here and
through direct email. I appreciate that very much. =)
I'm glad that my work is helpful to the community.
Greets,
Ertugrul.
Colin Paul Adams
"Daniel" == Daniel Carrera
writes: Daniel> Sam Martin wrote: >>> This is excellent: >>> >>> http://ertes.de/articles/monads.html >> >> Wow. That really is a great tutorial! Suddenly the world >> becomes clear... >> >> Definitely gets my vote as must read material.
Daniel> +1
Daniel> I was very impressed too. And I am not easy to impress Daniel> when it comes to documentation. I plan to read it a second Daniel> time to solidify some of the ideas, but on my first Daniel> reading my understanding of Monads increased by leaps and Daniel> bounds.
Daniel> Ertugrul deserves to be commended, and this tutorial Daniel> should be made more prominent on haskell.org.
I think so. I've read VERY MANY tutorials on monads, and they were all confusing - except this one.
-- nightmare = unsafePerformIO (getWrongWife >>= sex) http://blog.ertes.de/

On Thu, Apr 23, 2009 at 09:42:56PM +0200, Ertugrul Soeylemez wrote:
Hello people,
thanks for all your positive comments about my tutorial, both here and through direct email. I appreciate that very much. =)
I'm glad that my work is helpful to the community.
Would you provide a PDF version along with the HTML version? Regards, Romildo
Colin Paul Adams
wrote: > "Daniel" == Daniel Carrera
writes: Daniel> Sam Martin wrote: >>> This is excellent: >>> >>> http://ertes.de/articles/monads.html >> >> Wow. That really is a great tutorial! Suddenly the world >> becomes clear... >> >> Definitely gets my vote as must read material.
Daniel> +1
Daniel> I was very impressed too. And I am not easy to impress Daniel> when it comes to documentation. I plan to read it a second Daniel> time to solidify some of the ideas, but on my first Daniel> reading my understanding of Monads increased by leaps and Daniel> bounds.
Daniel> Ertugrul deserves to be commended, and this tutorial Daniel> should be made more prominent on haskell.org.
I think so. I've read VERY MANY tutorials on monads, and they were all confusing - except this one.

j.romildo@gmail.com wrote:
thanks for all your positive comments about my tutorial, both here and through direct email. I appreciate that very much. =)
I'm glad that my work is helpful to the community.
Would you provide a PDF version along with the HTML version?
That will require me to write another XSLT stylesheet, something which I was going to do anyway, but haven't done yet. If you would like to convert it yourself, you'll find the original source files here: * http://ertes.de/articles/monads.xml * http://ertes.de/articles/Article.xsl * http://ertes.de/articles/Article.rng Greets, Ertugrul. -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://blog.ertes.de/

While i agree to some extent that analogies are bad in some sense , i found
this one really insightful when i was trying to put my head around monads :
http://www.haroldtherebel.com/2007/12/02/monads-and-schroedingers-cat/
what do u guys think ?
On Fri, Apr 24, 2009 at 11:18 AM, Ertugrul Soeylemez
j.romildo@gmail.com wrote:
thanks for all your positive comments about my tutorial, both here and through direct email. I appreciate that very much. =)
I'm glad that my work is helpful to the community.
Would you provide a PDF version along with the HTML version?
That will require me to write another XSLT stylesheet, something which I was going to do anyway, but haven't done yet. If you would like to convert it yourself, you'll find the original source files here:
* http://ertes.de/articles/monads.xml * http://ertes.de/articles/Article.xsl * http://ertes.de/articles/Article.rng
Greets, Ertugrul.
-- nightmare = unsafePerformIO (getWrongWife >>= sex) http://blog.ertes.de/
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
-- Federico Brubacher www.fbrubacher.com Colonial Duty Free Shop www.colonial.com.uy

On Fri, Apr 24, 2009 at 5:37 PM, Federico Brubacher
While i agree to some extent that analogies are bad in some sense , i found this one really insightful when i was trying to put my head around monads : http://www.haroldtherebel.com/2007/12/02/monads-and-schroedingers-cat/
what do u guys think ?
I could be wrong here, but isn't he really describing functors and not monads? Michael

On Fri, Apr 24, 2009 at 05:53:22PM +0300, Michael Snoyman wrote:
On Fri, Apr 24, 2009 at 5:37 PM, Federico Brubacher
wrote: While i agree to some extent that analogies are bad in some sense , i found this one really insightful when i was trying to put my head around monads : http://www.haroldtherebel.com/2007/12/02/monads-and-schroedingers-cat/
what do u guys think ?
I could be wrong here, but isn't he really describing functors and not monads?
Well, it isn't quite clear, because the explanation seems sort of confused. The "monads are a box that you can keep stuff in but can't get stuff out of" metaphor is not new (google "monad space suit") and in my opinion is somewhat unhelpful, for several reasons: (1) with many monads, you CAN "get stuff out of the box"; but how you do so is specific to each monad. (2) As pointed out by Michael, the explanation in the linked blog post seems to conflate fmap and (>>=), or at least glosses over the difference. But this is a very crucial difference that you must understand to manipulate anything more concrete than imaginary boxes containing cats. -Brent

Federico Brubacher wrote:
While i agree to some extent that analogies are bad in some sense , i found this one really insightful when i was trying to put my head around monads :
http://www.haroldtherebel.com/2007/12/02/monads-and-schroedingers-cat/
what do u guys think ?
Personally, I don't find this analogy useful. Because monads are obviously not Schrödinger's cat, the analogy makes me feel like I don't actually have any idea of what monads are. There are other things that I thought were more confusing than useful: If you have a monad (m a) you do not "put a function (a -> b) into the box". First of all, the second parameter of the bind operator does not have the signature (a -> b). It has the signature (a -> m b). Another problem with saying box or wrapper, which Ertugrul pointed out when I said "wrapper" is that the monad may not always return the same result. To quote Ertugrul: "An IO computation can give different results in each run". Finally, the analogy with Schrödinger doesn't seem apt. The point of Schrödinger's cat is that he is simultaneously dead and alive until you open the box to make a measurement. This is not how monads behave. It is *not* a property of Schrödinger's cat that you can't interact with the cat. Sure you can, just make a measurement. Finally, this page doesn't have all the detailed explanation that is necessary to make an analogy really work. Daniel.

Daniel Carrera
While i agree to some extent that analogies are bad in some sense , i found this one really insightful when i was trying to put my head around monads :
http://www.haroldtherebel.com/2007/12/02/monads-and-schroedingers-cat/
what do u guys think ?
Personally, I don't find this analogy useful. Because monads are obviously not Schrödinger's cat, the analogy makes me feel like I don't actually have any idea of what monads are.
There are other things that I thought were more confusing than useful: If you have a monad (m a) you do not "put a function (a -> b) into the box". First of all, the second parameter of the bind operator does not have the signature (a -> b). It has the signature (a -> m b).
I think, this is rather an allusion to functors.
Another problem with saying box or wrapper, which Ertugrul pointed out when I said "wrapper" is that the monad may not always return the same result. To quote Ertugrul: "An IO computation can give different results in each run".
Monadic values (computations, containers, whatever you call them) are expressed intrinsically without a notion of running them. Running is something separate and specific to particular monads. There may be monads, which are not supposed to be "run", or for which "running" doesn't make any sense at all.
Finally, the analogy with Schrödinger doesn't seem apt. The point of Schrödinger's cat is that he is simultaneously dead and alive until you open the box to make a measurement. This is not how monads behave. It is *not* a property of Schrödinger's cat that you can't interact with the cat. Sure you can, just make a measurement.
Actually Schrödinger's cat is neither dead nor alive. Its state S is a unit vector living in a Hilbert space. The two possible measurement outcomes are also unit vectors in that vector space. They form an orthonormal basis, but S isn't equal to either of them. Measuring S means turning it into one of them, thereby destroying the original state. Greets, Ertugrul. -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://blog.ertes.de/

Ertugrul Soeylemez wrote:
Actually Schrödinger's cat is neither dead nor alive. Its state S is a unit vector living in a Hilbert space.
I spoke imprecisely, but I do know about superposition. I took a couple of quantum courses when I got my physics degree (but generally I focused on astrophysics which is far more interesting than quantum mechanics). Daniel.

Daniel Carrera
Actually Schrödinger's cat is neither dead nor alive. Its state S is a unit vector living in a Hilbert space.
I spoke imprecisely, but I do know about superposition. I took a couple of quantum courses when I got my physics degree (but generally I focused on astrophysics which is far more interesting than quantum mechanics).
I just wanted to justify why the cat is neither dead nor alive, not both at the same time, as seems to be the common sense about quantum mechanics. But of course, this is totally off topic here. =) Greets, Ertugrul. -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://blog.ertes.de/

With Ertugrul's permission, I've done a simple print-to-PDF of his
"Understanding Haskell Monads" tutorial, and am providing the PDF file
to this list.
-jn-
On Fri, Apr 24, 2009 at 5:11 AM,
On Thu, Apr 23, 2009 at 09:42:56PM +0200, Ertugrul Soeylemez wrote:
Hello people,
thanks for all your positive comments about my tutorial, both here and through direct email. I appreciate that very much. =)
I'm glad that my work is helpful to the community.
Would you provide a PDF version along with the HTML version?
Regards,
Romildo
Colin Paul Adams
wrote: >> "Daniel" == Daniel Carrera
writes: Daniel> Sam Martin wrote: >>> This is excellent: >>> >>> http://ertes.de/articles/monads.html >> >> Wow. That really is a great tutorial! Suddenly the world >> becomes clear... >> >> Definitely gets my vote as must read material.
Daniel> +1
Daniel> I was very impressed too. And I am not easy to impress Daniel> when it comes to documentation. I plan to read it a second Daniel> time to solidify some of the ideas, but on my first Daniel> reading my understanding of Monads increased by leaps and Daniel> bounds.
Daniel> Ertugrul deserves to be commended, and this tutorial Daniel> should be made more prominent on haskell.org.
I think so. I've read VERY MANY tutorials on monads, and they were all confusing - except this one.
Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
-- Beauty of style and harmony and grace and good rhythm depend on simplicity. - Plato

Here's a clearer description:class Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b Instances of Monad must satisfy the following laws: return a >>= k == k a m >>= return == m m >>= (k >>= h) == (m >>= k) >>= h Much more clear and concise, don't you think? On Wed, Apr 22, 2009 at 6:21 AM, Daniel Carrera < daniel.carrera@theingots.org> wrote:
I hate monads.
I love 90% of Haskell. The functional stuff is beautiful, easy to understand, crystal clear, elegant, etc. But I'm having a mighty hard time getting my head around monads. Consider the following explanation of a monad:
"A monad is represented as a type constructor (call it m), a function that builds values of that type (a -> m a), and a function that combines values of that type with computations that produce values of that type to produce a new computation for values of that type".
1) I know what a type is, but not a "type constructor". I don't normally think of an Int or even a complex type as being "constructed" except in the sense of OOP which I know is not what the author means.
2) Just *read* the paragraph... "a type constructor, a function that builds value of that type, and a function that combines values of that type with computations that produce values of that type to produce a computation of values of that type" Ugh....
Can anyone recommend a simple and clear explanation of monads? You can assume that I know basic math and basic Haskell syntax. So, for example, "a -> b" is much more clear than "a function that takes input of one type and has an output of a different type".
Any help would be appreciated.
Daniel. _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

Andrew Wagner wrote:
Here's a clearer description: class Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b
Instances of Monad must satisfy the following laws: return a >>= k == k a m >>= return == m m >>= (k >>= h) == (m >>= k) >>= h
Much more clear and concise, don't you think?
Actually, that /is/ clearer for me. Though I still think I'll need the tutorial Colin gave me to gain better intuition and understand the motivations behind monads. That said, I do have questions: 1) Am I right in thinking that any type with two elements ("m a") is always a Monad? (IO String, Maybe Int, etc). 2) When I say "m a >>= f" the >>= just pulls the "a" out of "m a" and passes it to "f". Right? 3) The last two properties are not comparing values but functions. Right? For example, reading the second-last property: (m >>= return) :: a -> m a Where (m >>= return) is defined by (\x -> m x >>= return). Right? And this is why you can write the last property: (k >>= h) :: a -> h a defined by (\x -> k a >>= h) This is what allows us to make (k >>= h) the second argument of ">>=" as in the last property: m >>= (k >>= h) == (m >>= k) >>= h Am I right? Thanks, Daniel.

1) Am I right in thinking that any type with two elements ("m a") is always a Monad? (IO String, Maybe Int, etc).
2) When I say "m a >>= f" the >>= just pulls the "a" out of "m a" and passes it to "f". Right?
3) The last two properties are not comparing values but functions. Right? For example, reading the second-last property:
(m >>= return) :: a -> m a
Where (m >>= return) is defined by (\x -> m x >>= return). Right? And this is why you can write the last property:
(k >>= h) :: a -> h a defined by (\x -> k a >>= h) This is what allows us to make (k >>= h) the second argument of ">>=" as in the last property:
m >>= (k >>= h) == (m >>= k) >>= h
Am I right?
I am also a beginner, so you should take my words with the grain of salt. Strange enough, the monad description that helped me most is the Wikipedia article: http://en.wikipedia.org/wiki/Monad_(functional_programming) This basically answers some of your questions by defining monad as triple (type constructor, bind function and return function), with certain properties. S.

2009/04/22 Daniel Carrera
1) Am I right in thinking that any type with two elements ("m a") is always a Monad? (IO String, Maybe Int, etc).
Well, no. Many such types are monads but not all of them. Monads have the monadic operations `return` and `>>=`.
2) When I say "m a >>= f" the >>= just pulls the "a" out of "m a" and passes it to "f". Right?
Yes. The `>>=` operators defines our evaluation strategy; it allows us to combine computations. Be carefult of confusing `m` (a type constructor) with the value constructors for a particular monad.
3) The last two properties are not comparing values but functions. Right? For example, reading the second-last property:
(m >>= return) :: a -> m a
Not quite -- `someMonadicValue >>= return` is of type `m a`.
Where (m >>= return) is defined by (\x -> m x >>= return). Right? And this is why you can write the last property:
(k >>= h) :: a -> h a defined by (\x -> k a >>= h) This is what allows us to make (k >>= h) the second argument of ">>=" as in the last property:
Actually, the third law is: (m >>= f) >>= g = m >>= (\x -> f x >>= g) -- Jason Dusek

Jason Dusek wrote:
Actually, the third law is:
(m >>= f) >>= g == m >>= (\x -> f x >>= g)
Yeah. I just saw that in the tutorial. And it actually makes more sense that way (esp after reading some of the tutorial): 1) A "computation" is something that may have a result. 2) In "m >>= f", m is a computation and f is a function that takes a value and returns a computation. >>= takes the output of m and makes it the input of f. 3) Therefore, the value of "m >>= f" is a computation. 4) Because "m >>= f" is a computation, it can be the left parameter of another >>=, as in "(m >>= f) >>= g". 5) If "x" is a value then "f x" is a computation. Thus, "f x" can be the left parameter of >>=, as in "f x >>= g", and the result of that is a computation. 6) Therefore, (\x -> f x >>= g) is a function that takes a value ("x") and returns a computation, so it can be the right parameter of >>=. I think I get it (at least this part). Cheers, Daniel.

2009/04/22 Daniel Carrera
I hate monads.
Yikes! How do you feel about functors?
1) I know what a type is, but not a "type constructor". I don't normally think of an Int or even a complex type as being "constructed" except in the sense of OOP which I know is not what the author means.
Well, an object constructor takes values and makes a value. A type constructor takes types and makes a type. You've probably seen a few type constructors in your life, for example, `std::vector`, which makes vectors of type `std::vector<t>`. Likewise, `std::map` is a two argument type constructor.
2) Just *read* the paragraph... "a type constructor, a function that builds value of that type, and a function that combines values of that type with computations that produce values of that type to produce a computation of values of that type" Ugh....
I don't think you should take your first impression too seriously here. The notion of combining computations is really crucial to working with monads; you'll find it's pretty hard to get used to at first, no matter how it's presented. -- Jason Dusek

Daniel Carrera wrote:
1) I know what a type is, but not a "type constructor". I don't normally think of an Int or even a complex type as being "constructed" except in the sense of OOP which I know is not what the author means.
[Int] is a type. [] itself is a type constructor, taking a type like Int and "constructing" a new type [Int] , a list of integers. In other words, a type constructor is like a function on types. Regards, apfelmus -- http://apfelmus.nfshost.com
participants (14)
-
Andrew Wagner
-
Brent Yorgey
-
Colin Paul Adams
-
Daniel Carrera
-
Ertugrul Soeylemez
-
Federico Brubacher
-
Heinrich Apfelmus
-
j.romildo@gmail.com
-
Jason Dusek
-
Joel Neely
-
Michael Snoyman
-
Sam Martin
-
Sergey V. Mikhanov
-
Thomas Davie