I am trying to understand Monad and I have the following code
f a b c d =
do one <- a + b
two <- c * d
three <- one + two
return three
The above compiles
but get the an error when I
*Main> f 1 2 3 4
:1:1:
No instances for (Num (a0 -> t0), Monad ((->) a0), Monad ((->) t0))
arising from a use of `f'
Possible fix:
add instance declarations for
(Num (a0 -> t0), Monad ((->) a0), Monad ((->) t0))
In the expression: f 1 2 3 4
In an equation for `it': it = f 1 2 3 4
:1:9:
No instance for (Num (a0 -> a0 -> t0))
arising from the literal `4'
Possible fix:
add an instance declaration for (Num (a0 -> a0 -> t0))
In the fourth argument of `f', namely `4'
In the expression: f 1 2 3 4
In an equation for `it': it = f 1 2 3 4
I think I would be one step closer to understand Monad if I know why the above code dont work on
f 1 2 3 4
The problem is you are confusing wrapped monadic values with pure values.
The first thing to know is that do notation is syntactic sugar for regular function calls (
>>=and>>). So, it would help to see what your code desugars too.Lets try something simpler
This has the same problem as your code, but is simpler. To understand why it doesn’t work we ask: what does this actually mean? Well, we can rewrite the
<-symbol using>>=(this is not the simplest representation, but makes the point clear)
If you test the following in GHCi
that is, the function
>>=takes: an argument of typemofaand a function fromatomofband returns amofb.What about in this code?
Is going to be a number.
How about the other half
Takes an object of type
aand returns an object of typem afor anyaSo, you need to have a number, that is also some sort of monad of something. Can you think of anything like that? It is not clear what this would be, which is a reason to be suspicious that this should type check.
One good way to come to terms with monads is to look at some specific examples.
The
Maybemonad expresses computations that might failThis lets you say things with a patter like
or the same code more simply
or perhaps
On the other hand the
Listmonad captures the idea of performing the same function on every element of a list, and then concatenating the results together. Simple examples abound:If you understand these ones, play with the
Statemonad. It helps you get the more general idea that “monads are models of computation.” I would then checkout Parsec, and of course, IO