2018-12-05 18:54
Page 1

Page 2

• It is a combination of λ and
`>>=`
• λ as in lambda, anonymous functions,
`\ x -> 2*x`
• The
`>>=`
operator in the
`Monad`
class.
Page 3

# Motivating example

## Instead of writing code like this:

```number :: String -> Maybe (Integer,String)
number s = case span isDigit s of
([],_) -> Nothing

addition :: String -> Maybe (Integer,String)
addition s = case number s of
Just (n1,'+':r) -> case number r of
Just (n2,r') -> Just (n1+n2,r')
_ -> Nothing
_ -> Nothing

multiplication :: String -> Maybe (Integer,String)
multiplication s = case number s of
Just (n1,'*':r) -> case number r of
Just (n2,r') -> Just (n1*n2,r')
_ -> Nothing
_ -> Nothing

calculation :: String -> Maybe (Integer,String)
calculation s = case addition s of
Nothing -> multiplication s
result -> result```
Page 4

## We can write code like this:

```number         = read <\$> oneOrMore (sat isDigit)
addition       = (+) <\$> number <* char '+' <*> number
multiplication = (*) <\$> number <* char '*' <*> number
Page 5

# Domain-specific languages

• The parser:
• ```number         = read <\$> oneOrMore (sat isDigit)
addition       = (+) <\$> number <* char '+' <*> number
multiplication = (*) <\$> number <* char '*' <*> number
• The grammar:
number ::= digit {digit}. addition ::= number "+" number. multiplication ::= number "*" number. calculation ::= addition | multiplication.
• Haskell is suitable as a host language in which you can embedd other (domain-specific) languages.
Page 6

# Types for functions with effects (1)

• Type of effectFunction type
Pure function:
`Input -> Output`
Extra input:
`Input -> Extra -> Output`
Extra output:
`Input -> (Extra,Output)`
Changing the state:
`Input -> State -> (State,Output)`
IO operations:
`Input -> IO Output`
Success or failure:
`Input -> Maybe Output`
Many results:
`Input -> [Output]`
• Can we factor out a common pattern?
Page 7

# Types for functions with effects (2)

• We can factor them like this:

Type of effectThe common patternThe difference
Pure function:
`Input -> M Output`

`M a`
=
`a`
Extra input:
`Input -> M Output`
`M a`
=
`Extra -> a`
Extra output:
`Input -> M Output`
`M a`
=
`(Extra,a)`
Changing the state:
`Input -> M Output`
`M a`
=
`State->(State,a)`
IO operations:
`Input -> M Output`
`M a`
=
`IO a`
Success or failure:
`Input -> M Output`
`M a`
=
`Maybe a`
Many results:
`Input -> M Output`
`M a`
=
`[a]`
• In all cases it can be seen as a modification of the return type!
• Sometimes we will need combinations of these effects.
Page 8

# Type classes related to monads

• ```class Functor f where
fmap :: (a->b) -> f a -> f b

f <\$> x = fmap f x```
• ```class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a->b) -> f a -> f b```
• ```class Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a->m b) -> m b

(=<<) :: Monad m => (a->m b) -> m a -> m b
f=<<x = x>>=f```
Page 9

# The do notation

• The
`do`
notation is translated into expressions using
`>>=`
• That's why it works for any monad!
• Example:  ```do x <- m1 y <- m2 x return (x+y)``` ⟹ ```m1 >>= \x -> do y <- m2 x return (x+y))``` ⟹ ```m1 >>= \x -> m2 x >>= \y -> return (x+y)```
Page 10

# Functor vs the do notation

• We have seen a few examples where using
`<\$>`
simplifies the code:
• ```rNumeric :: Gen Rank
rNumeric = do n <- choose (2,10)
return (Numeric n)
```
• ```rNumeric = Numeric <\$> choose (2,10)
```
• ```number :: Parser Integer
number = do ds <- oneOrMore digit
```
• `number = read <\$> oneOrMore digit`
Page 11

# Applicative vs the do notation

• Here are some examples where using
`<*>`
simplifies the code:
• ```rCard :: Gen Card
rCard = do s <- rSuit
r <- rRank
return (Card s r)
```
• `rCard = Card <\$> rSuit <*> rRand`
• ```oneOrMore :: Parser item -> Parser [item]
oneOrMore item = do i <- item
is <- zeroOrMore item
return (i:is)
```
• `oneOrMore item = (:) <\$> item <*> zeroOrMore item`
Page 12