Hi all,
 
> Concerning "2. combination with overlapping instances", you say "The
> solution has been described already in the HList paper: provide
> something the typeOf at the type level. That is, assume a type
> function "TypeOf :: * -> TYPEREP".
>
> ...
>
> Incidentally Pedro's new "deriving Generic" stuff does derive a kind of type-level type representation for types, I think.  It's more or less as described in their paper.
> http://www.dreixel.net/research/pdf/gdmh_nocolor.pdf

I'm very excited about this new Representable class and have just
started playing with it, so it is too early for me to say for sure.
However, my initial impression is that this is going to make me want
OverlappingInstances even more because of all the cool things you can
do with recursive algorithms over the Rep types...

Yes, most likely. I have a package defining a few generic functions and showing some example uses (http://hackage.haskell.org/package/generic-deriving). There I use OverlappingInstances (and even UndecidableInstances).
 

An initial issue I'm running into (and again, this is preliminary,
maybe I'll figure out a way without OverlappingInstances) is in
implementing a function to serialize Generic data types to JSON.  If
the Haskell data type has selectors (i.e., is a record), then I would
like to serialize/unserialize the type as a JSON object, where the
names of the selectors are the JSON field names.  If the Haskell data
type does not have selectors, then I would like to serialize it as a
JSON array.

Generic deriving gives me the conIsRecord function, but this is at the
value level, and I want to do something different at the type level.
For a record, I need a list of (String, Value) pairs, while for a
non-record, I need a list of Values.  This leads me to write code such
as the following:

 class JSON1 a r | a -> r
    toJSON1 :: a -> r

 instance (JSON a) => JSON1 (S1 NoSelector (K1 c a)) [Value] where
    toJSON1 (M1 (K1 a)) = [toJSON a]

 instance (Selector x, JSON a) => JSON1 (S1 x (K1 c a)) [(String, Value)] where
    toJSON1 s@(M1 (K1 a)) = [(nameOf s undefined, toJSON a)]
    where nameOf :: S1 c f p -> c -> String
          nameOf _ c -> selName c

The key piece of magic I need here (and in so many other places) is to
be able to do one thing at the type level if x is a particular type
(e.g., NoSelector) or sometimes one of a small number of types, and to
do something else if x is any other type.

Right. I think this is often essential.


Cheers,
Pedro