# The Extended Functor Family

## The Extended Functor Family

In addition to the standard `Functor`

class that you’ve used in this chapter,
there are other type classes that are related to `Functor`

but with somewhat
different behaviors.

#### Bifunctors

A `Bifunctor`

is like a `Functor`

but even moreso, because a `Bifunctor`

let’s
you map two different fields. The `Bifunctor`

class is defined in
`Data.Bifunctor`

. Let’s take a look at a definition for it:

```
class Bifunctor f where
bimap :: (a -> c) -> (b -> d) -> f a b -> f c d
first :: (a -> c) -> f a b -> f c b
= bimap f id
first f
second :: (b -> d) -> f a b -> f a d
= bimap id f second f
```

Try to write an instance of `Bifunctor`

for `Either`

.

#### Contravariant Functors

The `Contravariant`

class from `Data.Functor.Contravariant`

in base defines a
`_contravariant_`

functor. Although we don’t normally refer to them this way,
the `Functor`

class that you’ve been working with so far is a

```
class Contravariant f where
contramap :: (b -> a) -> f a -> f b
```

Try to create a new version of the `Function`

type that you defined earlier, and
then write an instance of `Contravariant`

for it. Can you also create an
instance of `Contravariant`

for your original definition of `Function`

? Why or
why not?

#### Profunctors

A `Profunctor`

is a combination of a `Bifunctor`

and a `Contravariant`

functor. `Profunctor`

isn’t defined in `base`

, but you’ll see it defined by some
other popular libraries. Like a `Bifunctor`

it works on types with two
arguments. Like `Contravariant`

functors, the first argument to a `Profunctor`

works “backwards”. Let’s take a look at a definition for `Profunctor`

:

```
class Profunctor f where
dimap :: (c -> a) -> (b -> d) -> f a b -> f c d
lmap :: (c -> a) -> f a b -> f c b
= dimap f id
lmap f
rmap :: (b -> d) -> f a b -> f a d
= dimap id f rmap f
```

Try to create an instance of `Profunctor`

for your original `Function`

type. Can
you write a valid instance? Why or why not? How does this differ from trying to
create a instance of `Contravariant`

for `Function`

?

### Hint 1

Some high level hint text

### Hint 2

Some more detailed hint text

### Hint 3

Even more detailed hint text

### Solution

A complete solution for the exercise