Hobby-hacking Eric

Showing posts with label monads. Show all posts
Showing posts with label monads. Show all posts

2009-02-21

implementing join in terms of (>>=)

One of the things I got out of the Typeclassopedia is a somewhat more mature understand of monads (at last!). As a bonus side-effect it has also given me a slightly better understanding of myself. Specifically, I learned I often have trouble learning things because I suffer from a sort of "failure to unify". I thought I might make a note of it for the benefit of anybody else who is interested in how they learn... or not, as the case may be.

So,
  • we have (>>=) :: m a -> (a -> m b) -> m b
  • we want join :: m (m x) -> m x
My mind drew a complete blank. So I went with something "direct" via do notation:
join mmx =
do mx <- mmx
x <- mx
return x
Those last two lines are redundant:
join mmx =
do mx <- mmx
mx

Hang on, Eric, surely you don't need the crutch of do notation...
join mmx = mmx >>= (\mx -> mx)
That's just id:
join mmx = mmx >>= id

But wait! Surely that can't be right! Doesn't (>>=) require something of type a -> m b? And isn't id giving me m x -> m x? I stared at that for a while, almost panicking. What did I do wrong? And then it clicked. Of course, the a in a -> m b could stand in for any type, including m x. Just because it doesn't have a little m in it, doesn't mean that it's constrained not to have one.

A simpler version of this kind of error, although one that didn't get me this time: just because we have a and b doesn't mean we actually have to have two different types. They can, but don't need to. And that, is my "failure to unify", inventing completely illusory constraints and not seeing through them.

And so join is just (>>= id). It took a little struggle, but it was well worth it!

(PS, in my original attempt, I used the more conventional m (m a) when thinking of the types instead of what I reported here, m (m x). The reason I reported the later is because I didn't want to confuse the discussion with another stumbling block I have, which is a "failure to rename", i.e. forgetting that two things called a in different contexts are actually two separate things. It's like speaking a foreign language. Just because you are aware that you have to do something, doesn't mean you will always do it automatically. Anyway, the "failure to rename" may very likely have conspired with the "failure to unify" in making me confused for a while)


2009-02-16

announcing: burrito tutorial support group

It's really for the best if you leave these sorts of things out in the open.



The first step is to ask for forgiveness, right?


2007-08-16

a history of monad tutorials

Here's a historical overview of monad tutorials since Phil Wadler's original observation that monads can be implemented in Haskell and become extremely useful.

When I wrote this, I originally wanted to do a real history, with an analysis of how people have tried to teach monads over the years, but I guess this is about all I have time for. Dates, authors and blurbs. Corrections/additions always welcome! As you can tell, I have not read them all.

Edit 2007-08-17: I have updated and moved this timeline to Haskellwiki. This might be useful when some future Haskell archeologist tries to figure out the precise "ah-ha!" moment when every single programmer in the world 'got' monads.


2007-01-31

think of a monad...

Think of a monad as a spacesuite full of nuclear waste in the ocean next to a container of apples. now, you can't put oranges in the space suite or the nucelar waste falls in the ocean, *but* the apples are carried around anyway, and you just take what you need. - Dons

Thought an illustration might be useful:


(Yes, yes, I know I have better things to be doing with my time)