But that is illegal in Haskell, because the heads of the two instance
declarations are identical. Nevertheless, you can code it up using
functional dependencies and overlapping instances, and that's what
this note describes.

These instances do make use of overlapping instances, but they do not
rely on the *context* to distinguish which one to pick, just the
instance *head*. Notice that (ShowPred ty flag) always succeeds! If
<ty> is a type for which there is a Show instance, flag gets unified
to HTrue; otherwise flag gets unified to HFalse.

The trick is to re-write a constraint (C a) which succeeds
of fails, into a predicate constraint (C' a flag), which always
succeeds, but once discharged, unifies flag with either HTrue or
HFalse. The desired invariant is

C a succeeds <--> C' a flag unifies flag with HTrue

Perhaps the most puzzling is the constraint (TypeCast flag HFalse) in
the first instance of ShowPred. The TypeCast constraint and its
important role are explained in Section 9 and specifically Appendix D
of the full HList paper
<http://homepages.cwi.nl/~ralf/HList/paper.pdf>

2 Notes and variations

There is only one instance of ShowPred and there is no overlapping
instances. Here, Showtypes are defined as

>type Showtypes =Int :+: Bool :+: Char :+: ... :+: HNil

(Polymorphic types like [a] take more effort, but they too can be handled).
This is the closed list of types, and HMember is a HList membership
checker. HMember uses TypeEq -- and the latter is the only place that
requires overlapping instances.

2. There is, of course, no check that the instances of ShowPred match
those of Show; you just have to get that right. An alternative, which
trades this problem for another, is instead to *replace* by Show',
which has the auxiliary flag:

classShow' a flag | a->flag where
show :: a -> String
-- This instance is used only if the others don't apply
instance TypeCast flag HFalse =>Show' a flag where
show = error "urk"
-- These instances are the regular ones
instance Show'Int HTrue whereshow= showInt
instanceShow' Bool HTrue where
show = showBool
...etc...