Some applicative style examples

I’m not going to define what an applicative functor is, (See references), but I would like to share some applicative style examples. After reading a bit about applicative functors I’ve coined the definition:

functors that can be applied, meaning functors containing functions
— My own :P

fmap on steroids ?

First step to use applicative functor style is to understand fmap and the infix notation <$>. When I try to apply a function to a value wrapped in a Functor normally I use fmap:

fmap (+1) (Just 1) == Just 2

But there’s the applicative style which uses the <$> symbol. The <$> symbol is just the fmap function, nothing else. The only difference is that you can use this symbol infix. That means the following would work the same:

(+1) <$> (Just 1) == Just 2

And there is another feature, <$> is left associative, that means among other things, you can avoid wrapping the right operand in parenthesis.

The magical <*>

But what if I wanted to do operations over wrapped values. And most of the time I use the do notation:

sumMaybe :: (Num a) => Maybe a -> Maybe a -> Maybe a
sumMaybe b c = do
  x <- b
  y <- c
  return (x + y)

This function means that for any applicative functor it would take the contained function () and the contained value (f a) and will return a contained value (f b).

Applicative
Apply f => f (a->b) -> f a -> f b

You can also use <*> in combination with <$> or in other words with fmap:

sumMaybe2 :: (Num a) => Maybe a -> Maybe a -> Maybe a
sumMaybe2 b c = (+) <$> b <*> c

Sometimes is easy to think that whenever you used to have a function receiving plain values you can use the same function but combining it as an applicative functor.

E.g here we have a function that creates a Band:

data Band = Band { id :: Long,
                   name :: String,
                   year :: Int}

createBand :: Long -> String -> Int -> Band
createBand id name year = Band { id = id, name = name, year = year }

That’s perfect, but what happens when have to create a Band from Maybe instances ? No problem, let’s use applicative functors:

createBand2 :: Maybe Long -> Maybe String -> Maybe Int -> Maybe Band
createBand2 id name year = createBand <$> id <*> name <*> year

What I’m doing is to partially apply the applied function with the first parameter, then with the second, and finally we resolve the function within the context.

List comprehensions

There is another use I’ve found specially interesting. The use of applicative functors for list comprehensions. Lets say I would like to increment every value from a given list. We can use map:

Using map
produceInc0 :: (Num a) => [a] -> [a]
produceInc0 xs = map (+1) xs

Or you may use list comprehensions:

Using comprehensions
produceInc1 :: (Num a) => [a] -> [a]
produceInc1 xs = [x + 1 | x <- xs ]

But there is still another way thanks to the applicative functor function <*>:

Using applicative functor style
produceInc2 :: (Num a) => [a] -> [a]
produceInc2 xs = [(+1)] <*> xs