I have a small question about value in context.
-
Take
Just 'a', so the value in context of typeMaybein this case is'a' -
Take
[3], so value in context of type[a]in this case is3 -
And if you apply the monad for
[3]like this:[3] >>= \x -> [x+3], it means you assignxwith value3. It’s ok.
But now, take [3,2], so what is the value in the context of type [a]?. And it’s so strange that if you apply monad for it like this:
[3,4] >>= \x -> x+3
It got the correct answer [6,7], but actually we don’t understand what is x in this case. You can answer, ah x is 3 and then 4, and x feeds the function 2 times and concat as Monad does: concat (map f xs) like this:
[3,4] >>= concat (map f x)
So in this case, [3,4] will be assigned to the x. It means wrong, because [3,4] is not a value. Monad is wrong.
I think your problem is focusing too much on the values. A monad is a type constructor, and as such not concerned with how many and what kinds of values there are, but only the context.
A
Maybe acan be ana, or nothing. Easy, and you correctly observed that.An
Either String ais either somea, or alternatively some information in form of aString(e.g. why the calculation ofafailed).Finally,
[a]is an unknown number ofas (or none at all), that may have resulted from an ambiguous computation, or one giving multiple results (like a quadratic equation).Now, for the interpretation of
(>>=), it is helpful to know that the essential property of a monad (how it is defined by category theorists) isTogether with
fmap,(>>=)can be written in terms ofjoin.What
joinmeans is the following: A context, put in the same context again, still has the same resulting behavior (for this monad).This is quite obvious for
Maybe (Maybe a): Something can essentially beJust (Just x), orNothing, orJust Nothing, which provides the same information asNothing. So, instead of usingMaybe (Maybe a), you could just haveMaybe aand you wouldn’t lose any information. That’s whatjoindoes: it converts to the “easier” context.[[a]]is somehow more difficult, but not much. You essentially have multiple/ambiguous results out of multiple/ambiguous results. A good example are the roots of a fourth-degree polynomial, found by solving a quadratic equation. You first get two solutions, and out of each you can find two others, resulting in four roots.But the point is, it doesn’t matter if you speak of an ambiguous ambiguous result, or just an ambiguous result. You could just always use the context “ambiguous”, and transform multiple levels with
join.And here comes what
(>>=)does for lists: it applies ambiguous functions to ambiguous values:can be rewritten as
since all you have to do is to find all possible results for each possible value.
This is why
joinisconcatfor lists, and in factmust hold in any monad.
A similar interpretation can be given to
IO. A computation with side-effects, which can also have side-effects (IO (IO a)), is in essence just something with side-effects.