# Lecture 8 — 2018-02-08

## Applicative

This lecture is written in literate Haskell; you can download the raw source.

A lot of this material is borrowed/based on two resources written by Brent Yorgey: his Haskell course from Spring 2013 and his Typeclassopedia. I encourage you to go read these excellent resources!

## A problem in Functortown

We looked at how we might define arithmetic evaluation with the possibility of errors:

```
evalA' :: Store -> AExp -> Either Error Int`
evalA' st (Neg e) = myNegate $ evalA' st e
where myNegate (Left err) = Left err
myNegate (Right n) = Right $ negate n
```

We observed that `myNegate = fmap negate`

, so we can instead write:

```
evalA' :: Store -> AExp -> Either Error Int`
evalA' st (Neg e) = negate <$> evalA' st e
```

(Recall that `(<$>)`

is the same thing as `fmap`

, but infix—it’s deliberately designed to look like application, `($)`

.)

We then tried to work out the case for `Plus`

:

```
evalA' :: Store -> AExp -> Either Error Int`
evalA' st (Neg e) = negate <$> evalA' st e
evalA' st (Plus e1 e2) = fmap2 (+) (evalA' st e1) (evalA' st e2)
```

What would this function `fmap2`

be? For our concrete example, we succeeded in defining a function:

```
fmap2 :: (a -> b -> c) -> Either e a -> Either e b -> Either e c
fmap2 _ (Left err1) _ = Left err1
fmap2 _ _ (Left err2) = Left err2
fmap2 f (Right v1) (Right v2) = Right $ f v1 v2
```

But can we go more general? We tried writing a different function `fmap2`

, but that didn’t go well either.

```
fmap2 :: Functor f => (a -> b -> c) -> f a -> f b -> f c
fmap2 f a b = undefined
where fa = fmap f a -- where do we go from here?
```

`Functor`

is a fine type class, but it only lets us operate opaquely. Once a function is trapped in `Functor`

, we can’t get it out!

A different type class, `Applicative`

, solves this problem.

```
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b -- pronounced 'ap'
```

NB that `Applicative`

is a subclass of `Functor`

.

```
fmap2' :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
fmap2' f a b = (fmap f a) <*> b
```

```
pure :: a -> f a
fmap :: (a -> b) -> f a -> f b
fmap2 :: (a -> b -> c) -> f a -> f b -> f c
```

Note that to be an `Applicative`

, you must be a `Functor`

. Can we write `fmap`

using the `<*>`

?

```
fmap' :: Applicative f => (a -> b) -> f a -> f b
fmap' f a = pure f <*> a
```

In fact, using `fmap`

with `Applicative`

s is so common that we have the definition `<$> = fmap`

.

```
fmap2Best :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
fmap2Best f a b = f <$> a <*> b -- note left associativity and tight binding of <$>
```

Finally, note that `fmap2`

is called `liftA2`

in Haskell.

### Obey the laws

Like `Functor`

, the `Applicative`

type class is governed by laws.

*Identity:* `pure id <*> v = v`

*Composition:* `pure (.) <*> u <*> v <*> w = u <*> (v <*> w)`

*Homomorphism:* `pure f <*> pure x = pure (f x)`

*Interchange:* `u <*> pure y = pure ($ y) <*> u`

Note that `identity`

is a generalization of `id <$> v = v`

from `Functor`

, since `f <$> x = pure f <*> x`

.

## Another way in

```
type Name = String
data Employee = Employee { name :: Name
, phone :: String }
deriving Show
maybeEmployee :: (Name -> String -> Employee) ->
(Maybe Name -> Maybe String -> Maybe Employee)
maybeEmployee f (Just n) (Just p) = Just $ f n p
maybeEmployee _ _ _ = Nothing
listEmployee :: (Name -> String -> Employee) ->
([Name] -> [String] -> [Employee])
listEmployee f n p = zipWith f n p
listEmployee' :: (Name -> String -> Employee) ->
([Name] -> [String] -> [Employee])
listEmployee' f n p = map (\(name,phone) -> f name phone) allPairs
where allPairs = Prelude.concat (map (\name -> map (\phone -> (name,phone)) p) n)
-- map (uncurry f) $ concatMap (\name -> map (\phone -> (name,phone)) p) n
funEmployee :: (Name -> String -> Employee) ->
(e -> Name) -> (e -> String) -> (e -> Employee)
funEmployee f mkName mkPhone = \e -> f (mkName e) (mkPhone e)
```

Another example of `Applicative`

, highlighting how it bears some similarity to normal “application”:

```
name :: Maybe String -> Maybe String -> Maybe String
name given family = (++) <$> given <*> family
drdave = name (Just "Dave") (Just "Kauchak")
prince = name (Just "Prince") Nothing
```

We wrote up a straightforward instance for `Maybe`

and a more interesting instance for `Either e`

:

```
instance Applicative (Either e) where
pure x = Right x -- because Left x would be ill typed!
(Right f) <*> (Right v) = Right $ f v
err@(Left e) <*> _ = err
_ <*> err@(Left e) = err
```

Then we (very quickly, at the end) went over the `Applicative`

definitions for lists. There were two possibilities: Cartesian product…

```
instance Applicative [] where
pure x = [x]
[] <*> _ = []
_ <*> [] = []
(f:fs) <*> xs = map f xs ++ fs <*> xs
```

…and zipping:

```
newtype ZipList a = ZipList { getZipList :: [a] }
deriving (Eq, Show, Functor)
instance Applicative ZipList where
pure = ZipList . repeat
ZipList fs <*> ZipList xs = ZipList (zipWith ($) fs xs)
```

(We wrote the infinite list differently, writing `pure x = x:pure x`

. That’s not *quite* right, because we want an infinite `ZipList`

, not an infinite list. The above definition is the technically correct one.)

Haskell prefers the former definition based on Cartesian product, because it doesn’t involve any infinite lists. Infinite lists are fine in Haskell, because Haskell is lazy… but even so, it’s very easy to accidentally use an infinite list to create an infinite loop. (For example, a map is fine, but a fold? Not always…)