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++. (>>=) :: 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). (>>=) :: 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.
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 `(>>=)`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: Nothinghttp://conal.net/blog/posts/everything-is-a-function-in-hask...