## (Covariant) Functor

Initually, functor is a mapping from one category to another, which preserves the structure of the origin one.

Formally, functor is defined as

A functor $F:C→D$ between categories $C$ and $D$ is a mapping of objects to objects and arrows to arrows, in such a way that:

- $F(f:A→B)=F(f):F(A)→F(B)$
- $F(g\cdot f)=F(g)\cdot F(f)$
- $F(1_A)=1_{F(A)}$

In Haskell:

```
class Functor f where
fmap ∷ (a → b) → f a → f b
```

## Contravariant^{1} Functor

A contravariant functor is like a functor but it reverses the directions of the morphisms. —— nLab

Basically it's the "reversed" version of covariant functor.

In Haskell:

```
class Contravariant f where
contramap ∷ (b → a) → f a → f b
```

## Bi(nary )Functor

Bifunctor is a functor which domain is the product of two categories.

ie.

For $C_1$, $C_2$ and $D$ categories, a functor $F:C_1\times C_2→D$ is a bifunctor.

```
class Bifunctor f where
bimap ∷ (a → c) → (b → d) → f a b → f c d
```

Examples of bifunctor include `Either`

and `(,)`

.

```
instance Bifunctor (,) where
bimap f g (x , y) = (f x , g y)
instance Bifunctor Either where
bimap f g = either (Left . f) (Right . g)
```

## Profunctor

A Profunctor is just a bifunctor that is contravariant in the first argument and covariant in the second. What's the problem? —— School of Haskell

So we just "reverse" the first argument of `Bifunctor`

:

```
class Profunctor f where
dimap ∷ (c → a) → (b → d) → f a b → f c d
```

A good example of profunctor is `(->)`

:

```
instance Profunctor (->) where
dimap ca bd ab = bd . ab . ca
```

^{1}

If you are familiar with "tradition" programming languages like Java or C#, you may have heard of "covariant" and "contravariant" before. For example, if type `A`

is subtype of `B`

, then `IEnumerable<A>`

is subtype of `IEnumerable<B>`

, so `IEnumerable<T>`

is covariant on `T`

. And similarly, `Action<T>`

is contravariant on `T`

. We can regard covariant and contravariant functors as more abstract (we weaken relationship from subtype to arbitrary binary relation) version of these types.