Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How binding works in function monads in Haskell?

Tags:

haskell

monads

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.

like image 786
Pavel Avatar asked Feb 17 '19 12:02

Pavel


People also ask

What does bind do monad?

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.

How do monads work Haskell?

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.

How do monads work?

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.

What are monads explain with example?

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.


Video Answer


2 Answers

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
like image 89
Willem Van Onsem Avatar answered Sep 22 '22 17:09

Willem Van Onsem


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)))
like image 44
Mark Seemann Avatar answered Sep 25 '22 17:09

Mark Seemann