# Functors

Welcome to our series on monads and other abstract structures in Haskell! Monads are one of those concepts that seems to cause of lot of fear and anguish among people trying to learn Haskell. The aim of this series is to show that they aren’t a scary or difficult concept, but can be easily understood by taking the proper steps.

In this first part of the series, we’ll start by learning about functors, a simpler abstract structure. If you already know about functors, feel free to move onto part 2, where we discuss applicative functors. If you know about both these concepts and want to dive straight into monads, head to part 3!

As a word of advice, this series will be a lot more beneficial if you can follow along with the code examples. If you’ve never installed Haskell or written a line of code, download our Beginners Checklist to find out how you can get started.

## A Simple Example

Here’s a simple example to start us on our way. This code converts an input string like “John Doe 24” into a tuple. We want to consider all inputs though, so the resulting type is a `Maybe`

.

```
tupleFromInputString :: String -> Maybe (String, String, Int)
tupleFromInputString input = if length stringComponents /= 3
then Nothing
else Just (stringComponents !! 0, stringComponents !! 1, age)
where
stringComponents = words input
age = (read (stringComponents !! 2) :: Int)
```

This simple function simply takes a string and converts it into parameters for first name, last name, and age. Suppose we have another part of our program using a **data type** to represent a person instead of a tuple. We might write a conversion function between these two different types. We want to account for the possibility of failure. So we’ll have another function handling that case.

```
data Person = Person {
firstName :: String,
lastName :: String,
age :: Int
}
personFromTuple :: (String, String, Int) -> Person
personFromTuple (fName, lName, age) = Person fName lName age
convertTuple :: Maybe (String, String, Int) -> Maybe Person
convertTuple Nothing = Nothing
convertTuple (Just t) = Just (personFromTuple t)
```

## A Change of Format

But imagine our original program changes to read in a **whole list** of names:

```
listFromInputString :: String -> [(String, String, Int)]
listFromInputString contents = mapMaybe tupleFromInputString (lines contents)
tupleFromInputString :: String -> Maybe (String, String, Int)
...
```

Now if we passed this result to the code using `Person`

, we would have to change the type of the `convertTuple`

function. It would have a parallel structure though. `Maybe`

and `List`

can both act as containers for other values. Sometimes, we don’t care how values are wrapped. We just want to transform whatever underlying value exists, and then return the new value in the same wrapper.

## Introduction to Functors

With this idea in mind, we can start understanding functors. First and foremost, `Functor`

is a **typeclass** in Haskell. In order for a data type to be an instance of the `Functor`

typeclass, it must implement a single function: `fmap`

.

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

The fmap function takes two inputs. First, it demands a function between two data types. The second parameter is **some container** of the first type. The output then is a container of the second type. Now let’s look at a few different `Functor`

instances for some familiar types. For lists, `fmap`

is simply defined as the basic map function:

```
instance Functor [] where
fmap = map
```

In fact, fmap is a **generalization of mapping**. For example, the Map data type is also a functor. It uses its own `map`

function for `fmap`

. Functors simply take this idea of transforming all underlying values and apply it to other types. With this in mind, let’s observe how `Maybe`

is a functor:

```
instance Functor Maybe where
fmap _ Nothing = Nothing
fmap f (Just a) = Just (f a)
```

This looks a **lot like our original** `convertTuple`

function! If we have no value in the first place, then the result is `Nothing`

. If we do have a value, simply apply the function to the value, and rewrap it in `Just`

. The `Either`

data type can be seen as a `Maybe`

type with more information about how it failed. It has similar behavior:

```
instance Functor (Either a) where
fmap _ (Left x) = Left x
fmap f (Right y) = Right (f y)
```

Note the first type parameter of this instance is fixed. Only the second parameter of an `Either`

value is changed by `fmap`

. Based on these examples, we can see how to rewrite `convertTuple`

to be **more generic**:

```
convertTuple :: Functor f => f (String, String, Int) -> f Person
convertTuple = fmap personFromTuple
```

## Making Our Own Functors

We can also take our **own data type** and define an instance of `Functor`

. Suppose we have the following data type representing a directory of local government officials. It is parameterized by the type `a`

. This means we allow different directories using different representations of a person:

```
data GovDirectory a = GovDirectory {
mayor :: a,
interimMayor :: Maybe a,
cabinet :: Map String a,
councilMembers :: [a]
}
```

One part of our application might represent people with tuples. Its type would be `GovDirectory (String, String, Int)`

. However, another part could use the type `GovDirectory Person`

. We can define the following `Functor`

instance for `GovDirectory`

by defining `fmap`

. Since our underlying types are mostly functors themselves, this just involves calling `fmap`

on the fields!

```
instance Functor GovDirectory where
fmap f oldDirectory = GovDirectory {
mayor = f (mayor oldDirectory),
interimMayor = f <$> interimMayor oldDirectory,
cabinet = f <$> cabinet oldDirectory,
councilMembers = f <$> councilMembers oldDirectory
}
```

Note `<$>`

is simply a synonym for `fmap`

. Now we have our own functor instance, sp transforming the underlying data type of our directory class is easy! We can just use:

`convertTuple <$> oldDirectory`

## Conclusion

Now that you know about functors, it's time to deepen your understanding of these kinds of structures. So move onto part 2 where we'll discuss applicative functors. If you’re dying to try out some of these examples but have never tried Haskell before, download our Beginners Checklist to learn how!