This post assumes prior knowledge of - the `Functor`

class
/ concept - the functor instance for `(->) r`

## Why

Not all higher kinded types `* -> *`

can have a
`Functor`

instance. While types like `Maybe a`

,
`(x, a)`

, `r -> a`

, `Either e a`

and
`[a]`

are `Functors`

in `a`

, there are
some types that cannot have a `Functor`

instance. A good
example is `Predicate`

:

`newtype Predicate a = Predicate { getPredicate :: a -> Bool }`

We call this type a predicate in `a`

because, given some
value of type `a`

we can obtain a `True`

or a
`False`

. So, for example: - `Predicate (> 10)`

is a predicate in `Int`

which returns true if the number is
greater than 10, - `Predicate (== "hello")`

is a predicate in
`String`

which returns true if the string is equal to
*"hello"*, and - `Predicate not`

is a predicate in
`Bool`

which returns the negation of the boolean value it
receives.

We can try writing a `Functor`

instance and see what we
can learn:

```
instance Functor Predicate where
fmap :: (a -> b) -> Predicate a -> Predicate b
fmap f (Predicate g) =
Predicate
$ \b -> _welp
```

As the type hole above would suggest, we need to return a
`Bool`

value, and we have: - `b :: b`

- ```
f ::
a -> b
```

- `g :: a -> Bool`

There is no way we can combine these terms at all, let alone in such
a way as to obtain a `Bool`

value. The only way we would be
able to obtain a `Bool`

value is by calling `g`

,
but for that, we need an `a`

-- but all we have is a
`b`

.

What if `f`

was reversed, though? If we had ```
f' :: b
-> a
```

, then we could apply `b`

to it ```
f' b ::
a
```

and then pass it to `g`

to get a `Bool`

.
Let's write this function outside of the `Functor`

class:

```
mapPredicate :: (b -> a) -> Predicate a -> Predicate b
Predicate g) =
mapPredicate f (Predicate
$ \b -> g (f b)
```

This looks very weird, compared to `Functor`

s, right? If
you want to go from `Predicate a`

to ```
Predicate
b
```

, you need a `b -> a`

function?

*Exercise 1*: fill in the typed hole `_e1`

:

```
greaterThan10 :: Predicate Int
= Predicate (> 10)
greaterThan10
exercise1 :: Predicate String
= mapPredicate _e1 greaterThan10 exercise1
```

*Exercise 2*: write `mapShowable`

for the following
type:

```
newtype Showable a = Showable { getShowable :: a -> String }
mapShowable :: (b -> a) -> Showable a -> Showable b
```

*Exercise 3*: Use `mapShowable`

and
`showableInt`

to implement `exercise3`

such that
`getShowable exercise3 True`

is `"1"`

and
`getShowable exercise3 False`

is `"2"`

.

```
showableInt :: Showable Int
= Showable show
showableInt
exercise3 :: Showable Bool
= exercise3
```

## How

`Predicate`

and `Showable`

are very similar,
and types like them admit a `Contravariant`

instance. Let's
start by looking at it:

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

The instances for `Predicate`

and `Showable`

are trivial: they are exactly `mapPredicate`

and
`mapShowable`

. The difference between `Functor`

and `Contravariant`

is exactly the function they receive: one
is "forward" and the other is "backward", and it's all about how the
data type is defined.

All `Functor`

types have their type parameter
`a`

in what we call a *positive* position. This
usually means there can be some `a`

available in the type
(which is always the case for tuples, or sometimes the case for
`Maybe`

, `Either`

or `[]`

). It can also
mean *we can obtain an a*, like is the case for

`r -> a`

. Sure, we need some `r`

to do that,
but we are able to obtain an `a`

afterwards.On the opposite side, `Contravariant`

types have their
type parameter `a`

in what we call a *negative*
position: they *need* to consume an `a`

in order to
produce something else (a `Bool`

or a `String`

for
our examples).

*Exercise 4*: Look at the following types and decide which can
have a `Functor`

instance and which can have a
`Contravariant`

instance. Write the instances down:

```
data T0 a = T0 a Int
data T1 a = T1 (a -> Int)
data T2 a = T2L a | T2R Int
data T3 a = T3
data T4 a = T4L a | T4R a
data T5 a = T5L (a -> Int) | T5R (a -> Bool)
```

As with `Functor`

s, we can partially apply higher kinded
types to write a `Contravariant`

instance. The most common
case is for the flipped version of `->`

:

`newtype Op a b = Op { getOp :: b -> a }`

While `a -> b`

has a `Functor`

instance,
because the type is actually `(->) a b`

, and
`b`

is in a *positive* position, its flipped version
has a `Contravariant`

instance.

*Exercise 5*: Write the `Contravariant`

instance
for `Op`

:

```
instance Contravariant (Op r) where
contramap :: (b -> a) -> Op r a -> Op r b
```

*Exercise 6*: Write a `Contravariant`

instance for
`Comparison`

:

`newtype Comparison a = Comparison { getComparison :: a -> a -> Ordering }`

*Exercise 7*: Can you think of a type that has both
`Functor`

and `Contravariant`

instances?

*Exercise 8*: Can you think of a type that can't have a
`Functor`

nor a `Contravariant`

instance? These
types are called `Invariant`

functors.