TypeFamilies vs. FunctionalDependencies & type-level recursion
dm-list-haskell-prime at scs.stanford.edu
dm-list-haskell-prime at scs.stanford.edu
Mon Jun 20 19:28:37 CEST 2011
At Mon, 20 Jun 2011 09:57:38 +0200,
José Pedro Magalhães wrote:
>
> 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.
One thing you could do to help in this specific case would be to use a
different M1 tag--e.g., M1 S ... for selectors and M1 NS ... for
fields without selectors (or K1 NS). I presume you've already
considered this and/or it's too late to make such a change. (Or to
move the distinction up to the constructor with two different
constructor tags, CR and CN for record and no-record.)
Anyway, as you mention, there are other situations where you still
need Overlapping/UndecidableInstances.
David
More information about the Haskell-prime
mailing list