# Functor, Applicative, and Why

This blog post will explain two core concepts in HaskellāāāFunctor and Applicative, which also exist in many other functional languages. Functor and Applicative are great abstractions that allow us to reuse lots of code.

However, when I was learning these concepts, it was difficult for me. Not just because theyāre abstract, but because most of the articles and posts I read about Functor and Applicative start by introducing their definition and then give examples.

I feel it should be the other way around. Itās easier to learn abstract things by seeing concrete instances or use cases of them.

So in this post, Iām starting with concrete examples then tying them back to the definitions of Functor and Applicative.

## Input validation

Letās say we have a `greet`

function in Javascript that takes a user object and returns a string:

```
var greet = function(user) {
return "Hello " + user.name;
};
```

If we try it in the node REPL, it should work.

```
> greet({ name: "Alice" })
'Hello Alice'
```

However, if we enter an `undefined`

value, it will throw an exception.

```
> greet(undefined)
TypeError: Cannot read property 'name' of undefined
...
```

Why would the `user`

be `undefined`

?

Well, Javascript is an untyped language, so any variable could be `undefined`

. This function assumes the input is not `undefined`

. But it's common for developers to forget about this assumption.

In order to handle the `undefined`

input, we could wrap this function with a function that validates the input:

```
var checkAndGreet = function(user) {
if (!user) {
return undefined;
}
return greet(user);
};
```

So if the user is `undefined`

, we wouldn't pass it to `greet`

, but short circuit to return `undefined`

.

## Maybe type in Haskell

Letās see how this case is handled in Haskell.

First, letās define the `User`

type and the `greet`

function.

```
data User = User String
deriving (Show)
greet :: User -> String
greet (User name) = "Hello " ++ name
```

Test it in GHCi:

```
> User "Alice"
User "Alice"
> greet (User "Alice")
"Hello Alice"
```

And letās visualize the function call like this:

In Haskell, this case is handled by a data type called `Maybe`

. This is the type declaration of `Maybe`

, which says the generic `Maybe`

type is either a `Just`

value that contains other values, or a constant `Nothing`

value.

```
data Maybe a = Nothing | Just a
deriving (Eq, Ord)
```

So `Maybe User`

is a type that can present two cases, either Nothing or a Just User.

If the input is a Maybe User, then we can make a `checkAndGreet`

to take that and return a `Maybe String`

.

```
checkAndGreet :: Maybe User -> Maybe String
checkAndGreet Nothing = Nothing
checkAndGreet (Just user) = Just (greet user)
```

The first line defines the `Maybe`

Letās try it in GHCi

```
> checkAndGreet Nothing
Nothing
> user = User "Alice"
> checkAndGreet (Just user)
Just "Hello Alice"
```

## How does it prevent mistakes?

Where would we get a `Maybe User`

?

Well, letās say we donāt want the user name to be empty, so we can create a `validateAndMakeUser`

function to check if the name is empty and returns a `Maybe User`

.

```
validateAndMakeUser :: String -> Maybe User
validateAndMakeUser "" = Nothing
validateAndMakeUser name = Just (User name)
```

Letās look at the mistake we had before.

If we have a user name of `String`

and we forget to validate the name and pass it directly to `greet`

, the Haskell compiler won't allow it. The compiler will say `greet`

takes a `User`

, which is not a `String`

.

```
> greet "Alice"
error:
ā¢ Couldn't match expected type āUserā with actual type ā[Char]ā
ā¢ In the first argument of āgreetā, namely ā"Alice"ā
In the expression: greet "Alice"
In an equation for āitā: it = greet "Alice"
```

If we remember to validate the name, and now we have a `Maybe User`

value, but still we passed it to `greet`

instead of `checkAndGreet`

, then the code won't compile either. Because `Maybe User`

and `User`

are different types.

```
> greet (Just (User "Alice"))
<interactive>:20:8: error:
ā¢ Couldn't match expected type āUserā with actual type āMaybe Userā
ā¢ In the first argument of āgreetā, namely ā(Just (User "Alice"))ā
In the expression: greet (Just (User "Alice"))
In an equation for āitā: it = greet (Just (User "Alice"))
```

## Extract the input validation part into a function

Alright. Letās say we have other functions that take `User`

and returns a different `String`

, for instance, a `bye`

function:

```
bye :: User -> String
bye (User name) = "Goodbye " ++ name
```

However, the input value we have is a `Maybe User`

value, not a `User`

. How can I take the `User`

from the `Maybe User`

and pass it to the `bye`

function?

Then we can wrap it the same way as `checkAndGreet`

to make a `checkAndBye`

.

```
checkAndBye :: Maybe User -> Maybe String
checkAndBye Nothing = Nothing
checkAndBye (Just user) = Just (bye user)
```

As you probably noticed, the `checkAndGreet`

and `checkAndBye`

are very similar. We're kind of repeating the logic here.

We could extract the common part into a function, and use that to make `checkAndGreet`

and `checkAndBye`

. Let's name this common function `mapUser`

.

```
mapUser :: (User -> String) -> Maybe User -> Maybe String
mapUser f Nothing = Nothing
mapUser f (Just user) = Just (f user)
checkAndGreet :: Maybe User -> Maybe String
checkAndGreet maybeUser = mapUser greet maybeUser
checkAndBye :: Maybe User -> Maybe String
checkAndBye maybeUser = mapUser bye maybeUser
```

We can further refactor them into point-free style:

```
checkAndGreet :: Maybe User -> Maybe String
checkAndGreet = mapUser greet
checkAndBye :: Maybe User -> Maybe String
checkAndBye = mapUser bye
```

With the generic `mapUser`

, you can get `checkAndGreet`

and `checkAndBye`

for free.

## Generalize the mapUser function

Letās take a look at the `mapUser`

function again. Even though this function is called `mapUser`

, it didn't actually use anything special about `User`

, nor about `String`

```
mapUser :: (User -> String) -> Maybe User -> Maybe String
mapUser f Nothing = Nothing
mapUser f (Just user) = Just (f user)
```

If we replace `User`

with a generic type `a`

and replace `String`

with a generic type `b`

, then `mapUser`

is equivalent to the `mapMaybe`

function as below:

```
mapMaybe :: (a -> b) -> Maybe a -> Maybe b
mapMaybe f Nothing = Nothing
mapMaybe f (Just a) = Just (f a)
```

Then we can refactor the `checkAndGreet`

and `checkAndBye`

with the `mapMaybe`

function, and it will still type-check and work.

```
checkAndGreet :: Maybe User -> Maybe String
checkAndGreet = mapMaybe greet
checkAndBye :: Maybe User -> Maybe String
checkAndBye = mapMaybe bye
```

Now we have a generic `mapMaybe`

function that can deal with a case where the input is empty (`Nothing`

).

With Haskellās strong type system, we can just write functions that process on concrete types, and if we need those functions to process the Maybe values we get them from DB calls or HTTP request, we can now just wrap the function with `mapMaybe`

to get a new function that is able to process over `Maybe`

values.

The `mapMaybe`

function can be implemented in Javascript too. Given there is no Maybe type, we would just call it `mapNullable`

:

```
var mapNullable = function(f) {
return function(v) {
if (v === null || v === undefined) {
return null;
}
return f(v);
};
};
var greet = function(user) {
return "Hello " + user.name;
};
var bye = function(user) {
return "Bye " + user.name;
};
var checkAndGreet = mapNullable(greet);
var checkAndBye = mapNullable(bye);
console.log(checkAndGreet({ name: 'Alice' })); // "Hello Alice"
console.log(checkAndBye(undefined)); // undefined
```

## Map over 2 Maybe values

Letās back to our Haskell version. We have a generic `mapMaybe`

to map a function over a `Maybe`

value. But it seems to only work for functions that take just one argument.

```
mapMaybe :: (a -> b) -> Maybe a -> Maybe b
```

What if my function takes more than one argument? Is it possible to have a function that maps over multiple `Maybe`

values? For example, `map2Maybes`

and `map3Maybes`

with the following type signatures:

```
map2Maybes :: (a -> b -> c) -> Maybe a -> Maybe b -> Maybe c
map3Maybes :: (a -> b -> c -> d)
-> Maybe a
-> Maybe b
-> Maybe c
-> Maybe d
```

And letās call a function that takes `N`

arguments an "N-arity" function. So `mapMaybe`

is 1-arity function, and `map2Maybes`

is 2-arity function, `map3Maybes`

is 3-arity function.

If we have the `map2Maybes`

function, then we can use it to wrap a function that takes two `Maybe User`

values as input.

```
showParents :: User -> User -> String
showParents (User fatherName) (User motherName) =
"Father is " ++ fatherName ++ " and mother is " ++ motherName
checkAndShowParents :: Maybe User -> Maybe User -> Maybe String
checkAndShowParents maybeFather maybeMother =
map2Maybes showParents maybeFather maybeMother
```

And the `map2Maybes`

is not hard to implement:

```
map2Maybes :: (a -> b -> c) -> Maybe a -> Maybe b -> Maybe c
map2Maybes _ Nothing _ = Nothing
map2Maybes _ _ Nothing = Nothing
map2Maybes f (Just a) (Just b) = Just (f a b)
```

Similarly, you can implement `map3Maybes`

, `map4Maybes`

... We can make as many as we want. However, we still need to write them manually each time for wrapping an N-arity function.

Is it possible to have a generic `mapNMaybes`

function that works for functions that take any number of arguments?

Letās find out.

## Map over N Maybe values

In Haskell, every function is curried. We can pass a value to a 2-arity function to get a new 1-arity function.

```
> :t showParents (User āBobā)
showParents (User āBobā) :: User -> String
```

Therefore, `showParents`

's type signature could also be written as:

```
showParents :: User -> (User -> String)
```

If we treat the 1-arity function `(User -> String)`

as a value, then `showParents`

can be passed to `mapMaybe`

and it will return a `Maybe (User -> String)`

type

```
> :t mapMaybe showParents (Just (User āBobā))
mapMaybe showParents (Just (User āBobā)) :: Maybe (User -> String)
```

But wait a second, can a `Maybe`

type contain a function?

Yes, why not? `Maybe a`

is a generic type, and it can take any concrete type to make a new type. Since a function is also a concrete type, it can be wrapped in a `Maybe`

value too. And it doesn't matter how many arguments it takes.

For instance, we can just pass any function to one of the Maybe type constructor `Just`

:

```
> :t Just greet
Just greet :: Maybe (User -> String)
> :t Just showParents
Just showParents :: Maybe (User -> User -> String)
```

But what can we do with a `Maybe (User -> String)`

value?

Well, letās take a look at what we need. Weād like to implement a `checkAndShowParents`

function.

```
checkAndShowParents :: (User -> User -> String)
-> Maybe User
-> Maybe User
-> Maybe String
```

Since weāve got

```
mapMaybe :: (User -> (User -> String))
-> Maybe User
-> Maybe (User -> String)
```

Or

```
mapMaybe :: (User -> User -> String)
-> Maybe User
-> Maybe (User -> String)
```

If we have another function with the following type signature, letās call it `applyShowParents`

for now.

```
applyShowParents :: Maybe (User -> String)
-> Maybe User
-> Maybe String
```

Then we can composite it with the `mapMaybe`

to make `checkAndShowParents`

:

```
checkAndShowParents :: Maybe User -> Maybe User -> Maybe String
checkAndShowParents maybeFather maybeMother =
applyShowParents (mapMaybe showParents maybeFather) maybeMother
applyShowParents :: Maybe (User -> String)
-> Maybe User
-> Maybe String
applyShowParents Nothing _ = Nothing
applyShowParents _ Nothing = Nothing
applyShowParents (Just f) (Just user) =
Just (f user)Generalize to applyMaybe
```

Again, we can generalize the `applyShowParents`

as well into a generic `applyMaybe`

function, because the function body doesn't need anything special from either `User`

or `String`

.

```
applyMaybe :: Maybe (a -> b) -> Maybe a -> Maybe b
applyMaybe Nothing _ = Nothing
applyMaybe _ Nothing = Nothing
applyMaybe (Just f) (Just a) = Just (f a)
```

And the `checkAndShowParents`

can be implemented by compositing `mapMaybe`

, `applyMaybe`

and `showParents`

```
checkAndShowParents :: Maybe User -> Maybe User -> Maybe String
checkAndShowParents maybeFather maybeMother = applyMaybe
(mapMaybe showParents maybeFather) maybeMother
```

## Generalize into N-arity function

Now that we can map over 2-arity functions, can it apply to N-arity functions?

Yes. Observe the `applyMaybe`

's type signature and how we can use it for a 3-arity functions or N-arity too:

```
applyMaybe :: Maybe (a -> b -> c) -> Maybe a -> Maybe (b -> c)
applyMaybe :: Maybe (a -> b -> c -> d)
-> Maybe a
-> Maybe (b -> c -> d)
applyMaybe :: Maybe (a -> b -> c -> d -> e)
-> Maybe a
-> Maybe (b -> c -> d -> e)
...
```

And with the following functions we can reduce a `Maybe`

N-arity function value into a `Maybe`

(N-1)-arity function value, which can be further reduced all the way to a `Maybe`

value.

```
> add3 a b c = a + b + c + (1 :: Int)
> :t add3
add3 :: Int -> Int -> Int -> Int
> :t applyMaybe (Just add3) (Just 1)
applyMaybe (Just add3) (Just 1) :: Maybe Int -> Maybe (Int -> Int -> Int)
> :t applyMaybe (applyMaybe (Just add3) (Just 1)) (Just 2)
:t applyMaybe (Just add3) (Just 1) :: Maybe Int -> Maybe (Int -> Int)
> :t applyMaybe (applyMaybe (applyMaybe (Just add3) (Just 1)) (Just 2)) (Just3)
:t applyMaybe (applyMaybe (applyMaybe (Just add3) (Just 1)) (Just 2)) (Just3) :: Maybe Int
```

The above expression looks a bit messy. Letās rewrite it as infix operator.

```
> Just add3 `applyMaybe` (Just 1) `applyMaybe` (Just 2) `applyMaybe` (Just 3)
Just 7
> Just add3 `applyMaybe` Nothing `applyMaybe` (Just 2) `applyMaybe` (Just 3)
Nothing
```

## Pattern of writing input validation for functions

Weāve made a generic `mapMaybe`

function and an `applyMaybe`

function that can be used to wrap any N-arity functions. That way, they're able to take values from N `Maybe`

and shortcircuit to return `Nothing`

if any of the N Maybe values are `Nothing`

.

```
greet :: User -> String
greet (User name) = "Hello " ++ name
checkAndGreet :: Maybe User -> Maybe String
checkAndGreet = mapMaybe
showParents :: User -> User -> String
showParents (User fatherName) (User motherName) =
"Father is " ++ fatherName ++ " and mother is " ++ motherName
checkAndShowParents :: Maybe User -> Maybe User -> Maybe String
checkAndShowParents maybeFather maybeMother =
showParents `mapMaybe` maybeFather `applyMaybe` maybeMother
add3 :: Int -> Int -> Int -> Int
add3 a b c = a + b + c + 1
checkAndAdd3 :: Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int
checkAndAdd3 ma mb mc = add3 `mapMaybe` ma
`applyMaybe` mb
`applyMaybe` mc
```

You might notice a pattern here: if we want to wrap an `N-arity`

function with empty input checks and the function has only 1 argument, we can just use `mapMaybe`

. If there is more than 1 argument, we just append (`applyMaybe`

argN) in the end.

## Functor and Applicative

OK, with the above examples and practices in mind, now itās time to introduce the term `Functor`

and `Applicative`

.

What is `Functor`

? `Functor`

is a typeclass that essentially defines a list of functions to implement.

`Functor`

typeclass defines just one function `fmap`

with the following type signature.

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

Recall the `mapMaybe`

function we created earlier. It's the `fmap`

function for `Maybe`

to be a `Functor`

. In other words, `Maybe`

is a Functor because `Maybe`

implements `fmap`

:

```
mapMaybe :: (a -> b) -> Maybe a -> Maybe b
mapMaybe f Nothing = Nothing
mapMaybe f (Just a) = Just (f a)
instance Functor Maybe where
fmap = mapMaybe
```

`fmap`

is also defined as the inflx operator `<$>`

. Therefore, the following two operations are identical:

```
infixl 4 <$>
(<$>) :: Functor f => (a -> b) -> f a -> f b
(<$>) = fmap
fmap greet (Just (User "Alice"))
greet <$> Just (User "Alice")
```

## What is Applicative?

`Applicative`

is also a typeclass. To be an `Applicative`

, the type has also to be a `Functor`

.

`Applicative`

defines two functions, `pure`

and `<*>`

, with the following type signature:

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

`Maybe`

is an instance of `Applicative`

. Refer to the type signature of `Just`

and `applyMaybe`

: these two functions are `Maybe`

type's implementation for being `Applicative`

.

```
Just :: a -> Maybe a
applyMaybe :: Maybe (a -> b) -> Maybe a -> Maybe b
class Applicative Maybe where
pure = Just
(<*>) = applyMaybe
```

The abstraction of `Functor`

and `Applicative`

allows more generic functions to be built and reused. For example, the `liftA2`

and `liftA3`

are generic versions of the `map2Maybes`

and `map3Maybes`

for `Applicative`

.

```
liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
liftA3 :: Applicative f => (a -> b -> c -> d)
-> f a
-> f b
-> f c
-> f d
```

Both `liftA2`

and `liftA3`

can be implemented with just `pure`

and `<*>`

. You can try to implement them yourself.

## More Functor examples

So far weāve seen an instance of `Functor`

and `Applicative`

, which is `Maybe`

. Actually, there are a lot more of them defined in the base module, and other modules.

The most useful Applicatives (which also means they are `Functor`

s) are `Maybe`

, `Either`

, `IO`

and `List`

, which means you can use the same functions `fmap`

, `(<*>)`

on all those types.

For instance, `IO`

is also a `Functor`

and an `Applicative`

. Here is an example of how to read and parse environment variables with the functions provided by `Functor`

and `Applicative`

.

To read the environment variables by name, there is a `getEnv`

function under the namespace `System.Environment`

that takes `String`

as the env var name and returns the env var as `IO String`

.

```
> import System.Environment (getEnv)
> :t getEnv
getEnv :: String -> IO String
```

`IO String`

is a computation that might run into an exception. For instance,

```
> getEnv "NAME"
*** Exception: NAME: getEnv: does not exist (no environment variable)
> ("NAME: " ++) <$> getEnv "NAME"
*** Exception: NAME: getEnv: does not exist (no environment variable)
> ("PORT: " ++) <$> getEnv "PORT"
"4567"
```

And we can make a `readConfig`

function by reusing the `<$>`

and `<*>`

function like this:

```
data Config = Config
{ cfgHost :: String
, cfgPort :: Int
, cfgDebug :: Bool
} deriving (Show)
readConfig :: IO Config
readConfig = Config <$> getHost
<*> getPort
<*> getDebug
getHost :: IO String
getHost = getEnv "HOST"
getPort :: IO Int
getPort = read <$> getEnv "PORT"
getDebug :: IO Bool
getDebug = read <$> getEnv "DEBUG"
```

Notice that the `read`

function is a polymorphic parse function that can be either `String -> Int`

or `String -> Bool`

depending on where it's used.

So if the environment doesnāt have `HOST`

, then the `IO`

will throw an exception:

```
> readConfig
*** Exception: HOST: getEnv: does not exist (no environment variable)
```

If all the environment variables are present, weāll get a `Config`

value with all the parsed value in it.

```
> readConfig
Config {cfgHost = "localhost", cfgPort = 4567, cfgDebug = True}
```

## Why?

To summarize my points with a few QnAs.

## Why do I need Functor?

Because we want to reuse code.

`Functor`

generalizes how to map a function from one value to another. We used the `Maybe`

type as an example to show why and how to use a generic `mapMaybe`

function without having to deal with the empty case. And the `mapMaybe`

is the implementation of `Functor`

for `Maybe`

type.

## Why do I need Applicative?

Because `Functor`

can only map a function which takes one argument. If we have a function that takes multiple arguments, we need `Applicative`

.

`Applicative`

provides abstraction for how to apply a function that takes multiple arguments over multiple values. We used `applyMaybe`

, which is the implementation of `Applicative`

for `Maybe`

type, as an example to show how to map a function over multiple `Maybe`

values without dealing with the case of any value being `Nothing`

.

## Why do I need Functor and Applicative instead of just mapMaybe and applyMaybe?

There are more instances of `Functor`

and `Applicative`

. For example, `Maybe`

, `Either`

, `IO`

, `List`

are all `Functor`

and `Applicative`

. You can reuse the same `fmap`

and `<*>`

function to map functions over those values without having to write `mapMaybe`

, `mapEither`

, `mapList`

, etc.

And functions like `liftA2`

, which is defined on top of `Functor`

and `Applicative`

, can also be reused for free without having to write `may2Maybes`

, `map2IOs`

, `map2Eithers`

etc.

## Conclusion

`Functor`

and `Applicative`

are two key concepts in functional programming. We used the `Maybe`

type and its use cases as examples to introduce the need for abstraction. `Functor`

and `Applicative`

are abstractions; they define what functions have to be implemented for a type to be an instance of them.

Functional programming has plenty more abstractions and type classes built on top of `Functor`

and `Applicative`

. This makes a great amount of code and logic reusable, and Haskell's strong type system ensures that the use of those generic functions are correct and safe.

Thanks for reading this blog post. Hopefully, I made `Functor`

and `Applicative`

a bit easier to understand.

Originally published on medium.com