Suppose we're writing some code to deal with bank accounts. Most of our code will refer to these using a proper data type. But less refined parts of our code might use a tuple with the same information instead. We would want a conversion function to go between them. Here's a simple example:

```
data BankAccount = BankAccount
{ bankName :: String
, ownerName :: String
, accountBalance :: Double
}
convertAccount :: (String, String, Double) -> BankAccount
convertAccout (bank, owner, balance) = BankAccount bank owner balance
```

Naturally, we'll want a convenience function for performing this operation on a list of items. We'll can use `map`

for lists.

```
convertAccounts :: [(String, String, Double)] -> [BankAccount]
convertAccounts = map convertAccount
```

But Haskell has a plethora of different data structures. We can store our data in a `Set`

, or a `Vector`

, for a couple examples. What if different parts of our code store the data differently? They would need their own conversion functions, since the list version of `map`

doesn't work on a `Set`

or `Vector`

. Can we make this code more generic?

## Functors

If you read the blog post a couple weeks ago, you'll remember the idea of typeclasses. This is how we can make our code generic! We want to generalize the behavior of running a transformation over a data structure. We can make a typeclass to encapsulate this behavior. Luckily, Haskell already has such a typeclass, called `Functor`

. It has a single function, `fmap`

. Here is how it is defined:

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

If that type signature looks familiar, that's because it's almost identical to the `map`

function over lists. And in fact, the `List`

type uses `map`

as it's implementation for `fmap`

:

```
map :: (a -> b) -> [a] -> [b]
instance Functor [] where
fmap = map
```

## Other Functor Instances

Now, `Set`

and `Vector`

do have `map`

functions. But to make our code generic, we have to define functor instances as a go-between:

```
instance Functor Vector where
fmap = Data.Vector.map
instance Functor Set where
fmap = Data.Set.map
```

With all this in mind, we can now rewrite `convertAccounts`

generically.

```
convertAccounts :: (Functor f) => f (String, String, Double) -> f BankAccount
convertAccounts = fmap convertAccount
```

Now anything can use `convertAccounts`

no matter how it structures the data, as long as it uses a functor! Let's looks at some of the other functors out there!

While it might not seem to fit in the same category as lists, vectors and sets, `Maybe`

is also a functor! Here's its implementation:

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

Another example of a functor is `Either`

. This one is a little confusing since `Either`

has two type parameters. But really, we have to fix the first parameter. Then the conversion function is only applied to the second. This means that, like with the `Nothing`

case above, when we have `Left`

, we return the original value:

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

## Conceptualizing Functors

So concretely, `Functor`

is a typeclass in Haskell. But how can we think of it conceptually? This is actually pretty simple. A functor is nothing more than a generic container or box. We don't know how many elements it contains. We don't know what the structure of those elements is. But if we have a way to transform those elements, we can apply that function over all of them. The result will be a new container with the same structure, but new elements. As far as abstractions go, this is probably the cleanest one we'll get, so enjoy it!

## Conclusion

Functor is an example of typeclass that we can use to get general behavior. In this case, the behavior is transforming a group of objects in a container while maintaining the container's structure. We saw how this typeclass allowed us to re-use a function over many different types. Functors are the simplest in a series of important typeclasses. Applicative functors would come next, and then monads. Monads are vital to Haskell. So understanding functors is an important first step towards learning more complex Haskell.

But you can't learn about data structures until you know the basics! If you've never written any Haskell before, download out Getting Started Checklist! If you're comfortable with the basics and want more of a challenge, take a look at our Recursion Workbook!