From learn you a haskell: http://learnyouahaskell.com/for-a-few-monads-more
Monad instance for function is this:
instance Monad ((->) r) where
return x = \_ -> x
h >>= f = \w -> f (h w) w
I am having trouble understanding the output of the following:
import Control.Monad.Instances
addStuff :: Int -> Int
addStuff = do
a <- (*2)
b <- (+10)
return (a+b)
addStuff 3
returns 19. Book says 3 gets passed as parameters to both (*2)
and (+10)
. How?
From h >>= f = \w -> f (h w) w
, it seems like (h w)
is getting bound to a or b.
So, why 6 is not being passed in (+10)?
My understanding of f
here is that when (*2)
is h
, f
is the last 2 lines of addStuff
. When (+10)
is h
, f
is the last line (in this case the return statement) of addStuff
.
A Monad consists of two interrelated functions: bind and unit. Bind takes a non-composable function f and returns a new function g that accepts the monadic type as input and returns the monadic type. g is composable. The unit function takes an argument of the type that f expected, and wraps it in the monadic type.
A monad is an algebraic structure in category theory, and in Haskell it is used to describe computations as sequences of steps, and to handle side effects such as state and IO. Monads are abstract, and they have many useful concrete instances. Monads provide a way to structure a program.
So in simple words, a monad is a rule to pass from any type X to another type T(X) , and a rule to pass from two functions f:X->T(Y) and g:Y->T(Z) (that you would like to compose but can't) to a new function h:X->T(Z) . Which, however, is not the composition in strict mathematical sense.
In functional programming, a monad is a software design pattern with a structure that combines program fragments (functions) and wraps their return values in a type with additional computation.
Let us first desugar the do
block [Haskell'10 report]:
addStuff = do
a <- (*2)
b <- (+10)
return (a+b)
is equivalent to:
addStuff = (*2) >>= \a -> ((+10) >>= \b -> return (a + b))
The inner bind expression ((+10) >>= \b -> return (a + b)
), can thus be converted, with the bind definition to:
\w -> (\b -> return (a + b)) ((+10) w) w
and if we substitute return
with const
, we thus obtain:
\w -> (const . (a+)) ((+10) w) w
We thus have a function that takes as input w
, and then calls const . (a+)
on (w+10)
and w
, so it will ignore the last w
. Semantically it is equivalent to:
(a+) . (+10)
So now our addStuf
is equivalent to:
addStuff = (*2) >>= \a -> ((a+) . (+10))
and if we now use the definition for the bind operator again, we see:
\w -> (\a -> ((a+) . (+10))) ((*2) w) w
or shorter:
\w -> (\a -> ((a+) . (+10))) (w*2) w
We can now substitue a
with (w*2)
and obtain:
\w -> ((w*2)+) . (+10)) w
So our addStuf
is equivalent to:
addStuff w = (w*2) + (w+10)
or more simple:
addStuff w = 3*w + 10
Haskell do
notation is syntactic sugar for a series of >>=
bindings; in this case, for something like this:
addStuff = (*2) >>= (\a -> (+10) >>= (\b -> return (a + b)))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With