For the past few months, I have been reading through Haskell Programming from First Principles. It is a wonderful book, worth reading carefully with many opportunities to develop a well-grounded understanding of Haskell, a challenging language with a wealth of powerful ideas.

This post will not cover any basics of installing Haskell and so on. Instead, look here for more on getting the language running on your machine. Also, if you're entirely new to Haskell and prefer working with free materials, see here for a great way to get started learning the language.

Recently, while reading the chapter on applicatives I encountered a practical example of how one might use applicatives with functors. While it might sound too abstract, the example below is actually readily understandable, especially if we proceed by thinking first and foremost about types and type signatures.

As a disclaimer, the example we will discuss comes straight out of Haskell Programming. This post is an attempt at reinforcing my own understanding of the example. Needless to say, an interested reader will read the chapters on functors and applicatives for the full context. In addition, there is also this incredible post on functors and applicatives which includes plenty of helpful visual guides as well as a nice introduction to the concepts.

Now for the example. Let's assume we have a type which represents a `Person`

. The `Person`

type includes a `Name`

and an `Address`

:

```
data Person =
Person Name Address
deriving (Eq, Show)
```

The `Name`

and `Address`

types are both wrappers around the `String`

type:

```
newtype Name =
Name String
deriving (Eq, Show)
newtype Address =
Address String
deriving (Eq, Show)
```

Before creating a `Name`

or `Address`

type, we will ensure the provided `String`

type satisfies a validation check: for names we will require no more than twenty-five characters. For addresses, we will require no more than 100 characters.

To handle validation, we will use a function which accepts a character limit (the `Int`

type) and a string (the `String`

type) which represents the name or the address.

```
validateLength :: Int -> String -> Maybe String
validateLength maxLen s =
if (length s) > maxLen
then Nothing
else Just s
```

What is interesting about this validation function is that it returns a `Maybe`

type. In other words, the validation can fail and when it does, its return value will be a `Nothing`

. Successful validation will result in the value wrapped in a `Just`

type. Both `Nothing`

and `Just`

are the two data constructors of the `Maybe`

data type.

Because `validateLength`

alternatively returns a `Just String`

or a `Nothing`

, we must handle the cases of both valid and invalid lengths when making a `Name`

or `Address`

. To do that, we will use `fmap`

, a function of the `Functor`

type class.

First, let's start with the two make functions:

```
mkName :: String -> Maybe Name
mkName s = fmap Name $ validateLength 25 s
mkAddress :: String -> Maybe Address
mkAddress a = fmap Address $ validateLength 100 a
```

Both the data contructors `Name`

and `Address`

take a `String`

and return a `Name`

or `Address`

data type. What then is this `fmap`

and how does it work with the `Maybe`

type?

Let's look at the `fmap`

function on its own for a moment starting with its type signature.

```
fmap :: Functor f => (a -> b) -> f a -> f b
```

The `fmap`

function applies a function to a value within a `Functor`

and returns a new `Functor`

with the transformed value.

Now, if we consider the types involved in `mkName`

for example, we'll see that `fmap`

does exactly what we need:

```
-- assuming some input
fmap Name (validateLength 25 "some-input")
-- we have these types
fmap (String -> Name) (Maybe String)
-- which match the signature of fmap
fmap (a -> b) -> f a
```

From the types above, we can see that `fmap`

will apply a function to the value within a `Functor`

(`Maybe`

in the case here) and then return a new `Functor`

(again a `Maybe`

type) with the transformed value within it (a `Maybe Name`

type). In Haskell parlance, we are lifting a function over structure.

So now that we have two `mk`

functions and understand their workings, we have a problem: how will we use `mkName`

and `mkAddress`

with the `Person`

data constructor, since it expects a `Name`

and an `Address`

object?

If we write a `mk`

function for our `Person`

type, it will need two string arguments:

```
mkPerson :: String -> String -> Maybe Person
mkPerson = undefined -- <- what goes here?
```

Both `mkName`

and `mkAddress`

return a `Maybe Name`

or a `Maybe Address`

. How can we use all three `mk`

functions together?

The answer is to use an applicative. To understand why, let's look at the type signature for the applicative operator `<*>`

:

```
-- :type (<*>)
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
```

The type signature for `<*>`

looks similar to `fmap`

above with the exception that the first argument -- a function -- is itself contained within an applicative structure. That wrapped function is then applied to the second argument -- an applicative wrapping a type which matches the function's input type -- and finally the output is an applicative wrapping a type of the function's return value.

Let's construct an example matching the types to help make this clear. What if we could use the `<*>`

operator with the following types? Would the types satisfy the type signature of `<*>`

?

```
Maybe (Address -> Person) <*> Maybe Address
```

We start with a `Maybe`

type wrapping a function which takes an `Address`

and returns a `Person`

. The right side of the `<*>`

operator is a `Maybe Address`

. Putting this next to the type signature of `<*>`

, we see the types line up perfectly:

```
f (a -> b ) <*> f a -- returns f b
Maybe (Address -> Person) <*> Maybe Address -- returns Maybe Person
```

Needless to say, `Maybe`

is a member of the `Applicative`

type class.

We know that `mkAddress`

takes a `String`

and returns a `Maybe Address`

, which means we can use it as part of our `mkPerson`

function. How then do we get a `Maybe (Address -> Person)`

?

We can use `fmap`

to produce exactly this function:

```
fmap Person (mkName String)
```

If we expand the types of the function above, we have:

```
fmap (Name -> Address -> Person) (Maybe Name)
-- which becomes
Maybe (Address -> Person)
```

We have used `fmap`

to apply the result of `mkName`

to our `Person`

data constructor, leaving a partially applied function which now takes an `Address`

and returns a `Person`

, all inside a `Maybe`

structure.

Putting all the pieces together, we have

```
mkPerson :: String -> String -> Maybe Person
mkPerson n a = (fmap Person (mkName n)) <*> mkAddress a
```

Or, swapping `fmap`

with its infix operator `<$>`

:

```
mkPerson :: String -> String -> Maybe Person
mkPerson n a = Person <$> mkName n <*> mkAddress a
```

And now we have a practical example of using applicatives with functors.