# Deriving Show for higher-kinded types

In a previous post, I used *reflection* to resolve constraints from derived `Show`

instances. But this method is still quite cumbersome because every constraint must be handled separately, and there can be as many of them as there are fields in our types.

Recently the problem of deriving `Show`

was brought up on this month’s Hask Anything thread on reddit, and I found a better solution.

We want to derive `Show`

for the following record type (a functor functor):

If we try to derive it simply…

… GHC first generates some code that looks roughly like this^{1}…

… in particular, it applies `show`

to each field; this requires the constraints `Show (f String)`

and `Show (f Int)`

, and they cannot be satisfied. Compilation fails.

We could add these constraints to the instance context. This works, but this solution doesn’t scale well to larger records with many types of fields.

What we really mean here is that there is an instance `Show a => Show (f a)`

, parametric in `a`

, and indeed the quantified constraints proposal will soon solve this problem.

However, here is a solution without quantified constraints, that can be used with currently released versions of GHC.

**The goal** is to define an instance…

… where `Show1`

is the closest approximation of the quantified constraint `forall a. Show a => Show (f a)`

we have at the moment. A function `show1`

is available to render a value of type `f a`

using a `Show1 f`

constraint^{2}.

**The idea** is that `deriving`

produces the code we want for the most part, and the result depends only on the “head” of the instance, `Bar`

here, so that the following declaration generates the same instance body (sketched above) for any `X`

and `Y`

.

These unknowns `X`

and `Y`

may be different from `Show1 f`

and `f`

respectively; we can still use that instance to then define the final instance `Show1 f => Show (Bar f)`

as follows…

… under the following conditions:

the constraint

`X`

is entailed by the context`Show1 f`

; we might as well be as general as possible, so`X = Show1 f`

;we can convert a

`Bar f`

to a`Bar Y`

, i.e., there is a function`convert :: Bar f -> Bar Y`

.

The function `convert`

should not modify the information contained in the record fields. This requirement is well met by `coerce`

. It literally does not touch its argument; it is a function between types that have the same runtime representation, and at runtime it behaves like the identity function. For `Bar f`

to be coercible to `Bar Y`

, the arguments `f`

and `Y`

must have the same representation. We can’t modify the abstract `f`

. Instead, we must pick `Y`

to be a newtype:

Looking at the derived instance, we thus have `show (b1 :: Showing f String)`

and `show (b2 :: Showing f Int)`

, and we expect the result to be equivalent to `show1 (unwrap b1 :: f String)`

and `show1 (unwrap b2 :: f Int)`

. This tells us exactly how to implement `Show`

for `Showing`

.

Note that this instance is not at all what the compiler would derive. In particular, the `Showing`

constructor is not rendered. The `Showing`

type is not as much a proper data type as it is a trick to transform a `Show`

constraint to a `Show1`

constraint.

We can now ask GHC to derive the following instance (more about `INCOHERENT`

below):

From that, we obtain the desired instance:

And that’s it!

Here is a condensed version of the code in this post.

### Little wrinkles

#### Just one function

The `show . (coerce :: _)`

pattern with an explicit type annotation can be condensed further into a single definition:

```
showing
:: forall h f
. (Coercible (h f) (h (Showing f)), Show (h (Showing f)))
=> h f -> String
showing = show . (coerce :: h f -> h (Showing f))
```

We can now refactor the last instance:

#### Overlapping instances

The two instances `Show (Bar (Showing f))`

and `Show (Bar f)`

overlap. Without any annotation, that is not allowed. Marking the former as `OVERLAPPING`

helps (or equivalently, the latter as `OVERLAPPABLE`

), but then the latter instance will only be picked when `f`

is instantiated to not unify with the first. This means that functions that are polymorphic in `f`

may incur a constraint `Show (Bar f)`

, rather than the simpler `Show1 f`

. Instead, marking the former instance as `INCOHERENT`

allows the compiler to ignore the overlap and just pick whichever instance is most convenient (usually the latter): `Showing`

is only an internal type for the purposes of deriving `Show`

, and shouldn’t be used elsewhere, so it is okay to assume that `f`

does not ever unify with `Showing g`

.

The derived code actually defines

`showsPrec`

first to deal with precedence levels, and then`show`

just wraps it.↩︎Actually there is

`showsPrec1`

to replace/implement`showsPrec`

.↩︎