This post assumes prior knowledge of

- the
`Functor`

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

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
mapPredicate f (Predicate g) =
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
greaterThan10 = Predicate (> 10)
exercise1 :: Predicate String
exercise1 = mapPredicate _e1 greaterThan10
```

*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
showableInt = Showable show
exercise3 :: Showable Bool
exercise3 =
```

`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.

Questions? Comments? Tweet them,
or post an issue on this
blog's github repo.