The codes below looks quite clear:
x <- Just 3
y <- Just "!"
Just (show x ++ y)
Here the type of
<- here is used to take actual value out of the Monad)
However, this snippet looks not so clear to me:
addStuff :: Int -> Int
addStuff = do
a <- (* 2)
b <- (+ 10)
return (a + b)
What is the type of
a and type of
b here? It seems they act like a
a <- (* 2) and
b <- (+ 10) looks cryptic here...
Does anyone have ideas about this?
Best How To :
Well, you've stumbled upon a kind of weird monad.
The monad in question is the
Monad ((->) r). Now, what does that mean? Well, it's the monad of functions of the form
r -> *. I.e., of functions that take the same type of input.
You asked what the type of
b are in this instance. Well, they are both
Num a => a, but that doesn't really explain much.
Intuitively, we can understand the monad like this: A monadic value is a function that takes a value of type
r as input. Whenever we bind in the monad, we take that value and pass it to the bound function.
I.e., in our
addStuff example, if we call
addStuff 5, then
a is bound to
(*2) 5 (which is
b is bound to
(+10) 5 (which is
Let's see a simpler example from this monad to try to understand how it works precisely:
mutate = do a <- (*2)
return (a + 5)
If we desugar this to a bind, we get:
mutate = (*2) >>= (\a -> return (a + 5))
Now, this doesn't help much, so let's use the definition of bind for this monad:
mutate = \ r -> (\a -> return (a + 5)) ((*2) r) r
This reduces to
mutate = \ r -> return ((r*2) + 5) r
Which we using the definition that
const, can reduce to
mutate = \ r -> (r*2) + 5
Which is a function, that multiplies a number by 2, and then adds 5.
That's one weird monad.