News for hackers. Stuff that matters.
Re:The Day Python Embarassed Imperative Programming by tmhedberg on Monday February 27, 2012 @08:20AM (#3638840)
Perhaps the author is just glossing over the bigger picture for the sake of explanation, but it's a bit of a narrow view of monads to say that they are just "conditional function calls". That's true if the monad in question is Maybe, Either e, or (if you're squinting at it just right) []. But >>= in the State s and IO monads, for instance, has little to do with conditionally calling functions; there, it's more about sequencing.

Beyond obeying some simple laws, there are strikingly few restrictions on the semantics of >>=. It can mean completely different things to different Monad instances. To me, that's at the heart of why newbies struggle to understand monads: >>= operates at a higher level of abstraction than many programmers are accustomed to. Outside of specific Monad instances, >>='s meaning is less significant than the structure that it imposes via the type system.

But that flexibility is also what makes Monad such a useful class in Haskell. Once your brain begins to recognize the `m a -> (a -> m b) -> m b` pattern in code, you see it everywhere. Monads are just a way of acknowledging that that particular structure exists in your code and abstracting it away to be replaced by a single operator. A chain of function calls with possible failure, like the author points out, is one case in which such a pattern emerges, but it's far from the only one. I think the article sort of misses that larger point.

Re:The Day Python Embarassed Imperative Programming by tripzilch on Monday February 27, 2012 @08:27AM (#3638859)

    m a -> (a -> m b) -> m b
Okay, so what does this mean? I thought it was `f x -> x * x` is a function definition, right? Or am I completely mistaken here? Because in the above code, what is the function name, the parameter and the return value? I know "everything is a function" in Haskell but I really can't see through the multiple arrows here. Any help?
Re:The Day Python Embarassed Imperative Programming by haberman on Monday February 27, 2012 @11:08AM (#3639414)
This is one of those things that functional-programming people seem to "get" without ever making the explanation very clear.

First of all, this is a function declaration (ie. prototype), not a definition. So this is describing a function type, not a function implementation. But that doesn't help very much because it's still not very obvious what the function type means.

The shortcut way to understanding Haskell function declarations is this; if you see:

  a -> b -> c -> d
in your head, think of it as:

  f(a, b, c) -> d
In other words, it is a function that takes three parameters of types a, b, and c and returns type d. Everything before the final -> is a parameter and the final type is a return type.

My "shortcut" isn't literally true, obviously. Here is the gory detail.

In Haskell, every function takes at most one parameter. Functions of multiple parameters do not exist; they are simulated through a technique called "currying." When you think you're calling a function of more than one parameter, you're actually calling a series of functions, each of which takes exactly one parameter. So in Haskell, if you call:

  f a b c
This is actually parsed as

  ((f a) b) c
Or in more C-like notation:

  f(a)(b)(c)
In other words, you call a function with a single parameter "a", which returns a function that you call with a single parameter "b", which returns a function that you call with a single parameter "c."

Likewise, the Haskell type declaration:

  a -> b -> c -> d
Is actually right-associative, so it's parsed as:

  a -> (b -> (c -> d)))
Which is why the whole thing works.

So to parse:

  m a -> (a -> m b) -> m b
Think of it as a function that would be called like so:

  f(m a, g) -> m b
Where g is a function that would be called like so:

  g(a) -> m b
The "m a" and "m b" business you can think of as being a lot like M<a> and M<b> in C++.
Re:The Day Python Embarassed Imperative Programming by tripzilch on Tuesday February 28, 2012 @07:14PM (#3645749)
Thank you! It's coming back to me now :) This was taught to me in college, I know about currying, the right-associativity was the big part I missed!
Re:The Day Python Embarassed Imperative Programming by danieldk on Monday February 27, 2012 @08:45AM (#3638924)
It's actually more insightful to see the full type signature:

  (>>=) :: Monad m => m a -> (a -> m b) -> m b
So, >>= is a function that takes:

- A value a in a monadic type m

- A function (a -> m b): a function that takes a value a and returns a value b wrapped in the monadic type m.

And it returns:

- A value b wrapped in the monadic type m.

It helps to look at the definition of (>>=) for a particular monad. The article mostly discusses computations that can fail (None vs an object in Python). The corresponding Haskell monads are Maybe and Either. The signature for (>>=) in the Maybe monad is:

    (>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
What the grandparent points out is that a monad defines a structure (how to combine expressions that result in wrapped values), but not semantics. The semantics are defined in the definition of a particular monad. E.g. the Maybe monad models failure in computation, while a monad such as MonadRandom does something different altogether (providing random numbers, while threading the state of the random number generator).
Re:The Day Python Embarassed Imperative Programming by tmhedberg on Monday February 27, 2012 @08:36AM (#3638892)
Sorry for not being clear. That's just the (abbreviated) type signature of >>=, which is formally written as

    (>>=) :: Monad m => m a -> (a -> m b) -> m b
It's not the definition of >>=, though. The definition is left up to the specific Monad instance that's defining it (which is basically the larger point that I was trying to make).

In English, that type signature basically says that >>= is a function which takes a monad and a function that operates on the monad's "contents" as its arguments, and returns the result of applying the function to the monad's contents. Any data type for which that abstract structure makes sense (and that also complies with the basic "monad laws") can be made an instance of Monad and provide its own definition for how >>= operates. That definition can be wildly different for different data types; the specific definition that the article focuses on is the one for the Maybe type.

Re:The Day Python Embarassed Imperative Programming by masklinn on Monday February 27, 2012 @09:04AM (#3638970)
> Okay, so what does this mean? I thought it was `f x -> x * x` is a function definition, right? Or am I completely mistaken here?

In this case, it's a type signature for a curried function. So

    a -> m b
is a function taking a value of type `a` and returning a value of type `m b`. In C# you would write:

    Function<A, M<B>>
so `m a -> (a -> m b) -> m b` is a function taking a value of type `m a` and a function with signature `a -> m b` and returning a function of type `m b`. Translating to C# again,

    Function< M<A>, Function<A, M<B>>, M<B> >
> Or am I completely mistaken here?

Pretty much yeah. In haskell, a function is either a top-level binding:

    someFunction arg = doSomething arg
or an anonymous function which is introduced by the character `\` (because `\` looks like `λ`, kind-of):

    \arg -> doSomething arg
In the expression you quoted, there is no function name, these are all types. The function name in this case is `(>>=)`
Re:The Day Python Embarassed Imperative Programming by yogsototh on Monday February 27, 2012 @08:39AM (#3638902)
m a: means a type which take a parameter (another type).

For example,

data Maybe a = Nothing | Just a

    - The m is for "Maybe"
    - The a is for "a"
For example:

    (>>=) (Just 3) (\ x -> Just (show x))
should returns: Just "3".

    (>>=) Nothing (\x -> Just (show x))
better written

    Nothing >>= (\x -> Just (show x))
should returns: Nothing
Re:The Day Python Embarassed Imperative Programming by jamiltron on Monday February 27, 2012 @12:25PM (#3639697)
Not to be nit-picky, but everything is Haskell is not always a function:

http://conal.net/blog/posts/everything-is-a-function-in-hask...

Re:The Day Python Embarassed Imperative Programming by rmcclellan on Monday February 27, 2012 @05:49PM (#3641012)
I completely agree. It's hard for beginners to learn that a monad isn't a thing, it's an property that can apply to many different things. A monad is so general it's hard to have a single intuition about it.

I think perhaps another reason why beginners find monads so hard to understand, especially those coming from a math background, is that >>= is a bizarre presentation of monads. I think, for example, defining a monad as an applicative with a join operation would have been a much better idea - most monads, like Maybe or [], make the most sense to me as "containers" that can be joined. The bind operator never really made intuitive sense to me when thinking about a monad as a container with a structure. Plus, to me, m (m a) -> m a is a lot easier to recognize than m a -> (a -> m b) -> m b.

This is especially true since applicatives are now becoming a very popular language idiom. It seems unfair to beginners to make them try to understand applicatives and then make them learn an unrelated typeclass for monads, when mathematically the two are very similar objects.

Re:The Day Python Embarassed Imperative Programming by Figs on Monday February 27, 2012 @08:45AM (#3638921)
Actually, I'm pretty sure the reason most people have trouble understanding monads in Haskell is because they haven't learned what typeclasses are yet. Once you know what a typeclass is, the rest is pretty straightforward.

I tried to explain it here ( http://www.reddit.com/r/programming/comments/erzh1/monads_ar... ) a while ago, which might be helpful for some people. Although, the version of List's >>= function is much easier to understand here ( http://en.wikibooks.org/wiki/Haskell/Advanced_monads#The_Lis... ) than the one I pulled out of GHC's library code.