TypeFamilies vs. FunctionalDependencies & type-level recursion
José Pedro Magalhães
jpm at cs.uu.nl
Mon Jun 20 09:57:38 CEST 2011
> > 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)]
> 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.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Haskell-prime