TypeFamilies vs. FunctionalDependencies & type-level recursion

José Pedro Magalhães jpm at cs.uu.nl
Mon Jun 20 09:57:38 CEST 2011


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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-prime/attachments/20110620/ffa9690a/attachment.htm>


More information about the Haskell-prime mailing list