@jyrimatti

## motivation

• monads are so last millenium.
We should already know what they are
• it's useful to know and understand abstractions,
even those we don't directly need in our everyday life
• I'll buy you a beer if you find this presentation useful ;)

## disclaimer

In addition to it begin useful, it is also cursed and the curse of the monad is that once you get the epiphany, once you understand - "oh that's what it is" - you lose the ability to explain it to anybody.
-- Douglas Crockford

## spoiler

it's not a burrito

http://www.carlosandgabbys.com/chicken%20burrito.jpg

## a function

In mathematics, a function is a relation between a set of inputs and a set of permissible outputs with the property that each input is related to exactly one output.
http://en.wikipedia.org/wiki/Function_(mathematics)
``````
f :: a -> b
``````

## function composition

In mathematics, function composition is the pointwise application of one function to the result of another to produce a third function.
http://en.wikipedia.org/wiki/Function_composition
``````
compose :: (b -> c) -> (a -> b) -> (a -> c)
compose g f = \a -> g (f a)
= g . f
``````
• "chaining" functions together
• notice how this enforces an order for the function applications

## function application

in mathematics, function application is the act of applying a function to an argument from its domain so as to obtain the corresponding value from its range.
http://en.wikipedia.org/wiki/Function_application
``````
apply :: (a -> b) -> a -> b
``````

what if our values are "boxed", inside:

• an Option/Optional/Maybe?
• a Wicket IModel?
• a JavaScript Promise?
• a List?
• ...
``````
noWay :: Bool -> Bool
someValue :: Maybe Bool

noWay someValue -- whoops, won't compile
``````

## a functor

In mathematics, a functor is a type of mapping between categories, which is applied in category theory.
http://en.wikipedia.org/wiki/Functor

just forget that.

• "something that can be mapped over"
• a boxed value
• a value with a context
``````
class Functor f where
fmap :: (a -> b) -> f a -> f b
``````
now this works:
``````
noWay :: Bool -> Bool
someValue :: Maybe Bool

(fmap noWay) someValue -- hooray!
``````
• generalizes function application to work with boxed values
• you probably shouldn't think of them as boxes.
or maybe you should.
I don't know.
• there's so little structure that the abstraction stays simple

what if our function takes more parameters?

``````
orElse :: Bool -> Bool -> Bool

(fmap orElse) :: Maybe Bool -> Maybe (Bool -> Bool) -- whoops...
``````

return value wrapped inside the container,
need something capable of handling this

## an applicative

``````
class Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
``````

notice how the signature is just what we needed

now this works:
``````
orElse :: Bool -> Bool -> Bool
someValue :: Maybe Bool

(pure orElse) <*> someValue <*> someValue -- hooray!
``````
• b can be a function, so this can be applied multiple times
• does not say anything about the order of execution,
so inherently parallelizable
• generalizes boxed function application to work
with functions of arity > 1

what if we want to interact with the box?

that is, affect the execution based on computed values?

that is, determine execution based on context?

``````
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
``````

we have a wrapped value, and we add "actions" to it one by one

```
(return 1)
>>= (\one -> return (one + 1))
>>= (\two -> return (two + 1))
-- and so on...
```

notice how this enforces the order of execution

## intuition?

we can change the order of arguments:

`(>>=) :: m a        -> (a -> m b) -> m b`
`(=<<) :: (a -> m b) -> m a        -> m b`

now the first part (the initial monadic value) can be given last:

```
(\one -> return (one + 1)
>>= (\two -> return (two + 1)))
=<< (return 1)
```

simplify syntax:

```
(a -> m b
>>= (b -> m c))
=<< m a
```

compare to function composition,
whose arguments may as well be interchanged:

`(.)   :: (b -> c) -> (a -> b) -> (a -> c)`
`(>>>) :: (a -> b) -> (b -> c) -> (a -> c)`
```
(a -> b)
>>> (b -> c)
\$ a
```

to work with functions returning boxed values

## lifting

Lifting is a concept which allows you to transform a function into a corresponding function within another (usually more general) setting.

functor/applicative/monad can be thought of as
an alternative way to apply functions

```
apply :: (a -> b) -> a -> b
fmap  :: (a -> b) -> f a -> f b
(<*>) :: f (a -> b) -> f a -> f b
(=<<) :: (a -> m b) -> m a -> m b
```

or a function can be thought to be lifted to another context

```
fmap   :: (a -> b) -> (f a -> f b)
liftA2 :: (a -> b -> c) -> (f a -> f b -> f c)  -- and liftA, liftA3, ...
liftM2 :: (a -> b -> c) -> (m a -> m b -> m c)  -- and liftM, liftM3, ...
```

## syntax

• binding actions to a Monad one after another while retaining all intermediate variables in scope, is a pattern also known as callback hell
• using a common abstraction throughout a language lets us add some syntactic sugar to ease the pain
• in Haskell that sugar is the do-notation, which transforms the callback-tree to an imperative-looking list of actions

anyway, it's just syntax

## laws

all these concepts must satisfy certain laws to ensure they are well behaved

we will not go there now =)

Monads have nothing to do with IO

...but IO needs the order of execution, which happens to be just the concept that a monad can provide

## going further

``````
class Functor f where
fmap :: (a -> b) -> f a -> f b
``````
``````
class Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
``````
``````
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b -- or: =<< :: (a -> m b) -> m a -> m b
``````
``````
apply ::   (a -> b) -> a -> b
fmap  ::   (a -> b) -> f a -> f b
(<*>) :: f (a -> b) -> f a -> f b
=<<   :: (a -> m b) -> m a -> m b
``````

anything missing?

``````
??    :: (w a -> b) -> w a -> w b
``````
• YES, there is!