### From Chen's Wiki

## Contents |

### Monad

My new and much more valueable post talking about monad implementation can be found here

#### The question

Evantually here it comes!

*How do you feed a function which take a normal value and return a value under context with a value under context?*

#### Defination in Haskell

We want this:

(>>=) :: (Monad m) => m a -> (a -> m b) -> m b

Formally, the whole thing is:

class Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b (>>) :: m a -> m b -> m b x >> y = x >>= \_ -> y fail :: String -> m a fail msg = error msg

However, we just need to focus on the *>>=* which reads *bind* and the *return*.

*return* does nothing with the imperative *return* in Python. You can see that it just does the same thing as *pure*.

#### Python example

def unit(x): #the "return" return [x] def bind(x, f): #the ">>=" return flatten(map(f, x)) def flatten(xs): return [x for sub in xs for x in sub] print bind([1, 2], lambda x: unit(x+1)) print bind([1, 2], lambda x: bind([1, 2], lambda y: unit((x, y)))) #[2, 3] #[(1, 1), (1, 2), (2, 1), (2, 2)]

It is actually straightforward. The only tricky part here for a list monad is that a use of **flatten**. This makes the return value still the same with the original function.

Things making it ugly are

- It is hard to make a infix ">>=" operator in Python. Let's try working around this [a bit]
- Python does not support
**currying**by default so we have to use a chain of lambdas.

#### Full version

I have tried to describe these functional concepts step by step, starting from the functors in another article. Functor, Applicative, Monads in Python

#### Comments