The codes below looks quite clear:
do
x <- Just 3
y <- Just "!"
Just (show x ++ y)
Here the type of x
is Num
and y
is String
. (<-
here is used to take actual value out of the Monad)
However, this snippet looks not so clear to me:
import Control.Monad.Instances
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 Num
, but a <- (* 2)
and b <- (+ 10)
looks cryptic here...
Does anyone have ideas about this?
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 formr -> *
. I.e., of functions that take the same type of input.You asked what the type of
a
andb
are in this instance. Well, they are bothNum 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 calladdStuff 5
, thena
is bound to(*2) 5
(which is10
), andb
is bound to(+10) 5
(which is15
).Let's see a simpler example from this monad to try to understand how it works precisely:
If we desugar this to a bind, we get:
Now, this doesn't help much, so let's use the definition of bind for this monad:
This reduces to
Which we using the definition that
return
isconst
, can reduce toWhich is a function, that multiplies a number by 2, and then adds 5.
That's one weird monad.