Suppose I have a data type like
data D a = D a a a
and a typeclass
class C c ...
instance (C c1, C c2) => C (c1, c2)
Then, I want to be able to write
data D a = D a a a deriving C
and have that generate an instance,
instance C ((a, a), a) => C (D a)
by using the modulo-lazy-evaluation isomorphism,
D a ~ ((a, a), a)
Note. Using a newtype and GeneralizedNewtypeDeriving will not work if, for example, one has data D m = D (m Integer) (m Integer).
Note 2. This question has relevance for Haskell expressiveness in general — languages like Python have something called named tuples, which can be used anywhere tuples are used; this question shows where/how I don’t know how to emulate the same thing in Haskell.
You can do this relatively cleanly and efficiently using GHC 7.4’s generic programming support. The documentation for GHC.Generics may be helpful. Here’s an example.
Consider the following example class and some sample instances:
We need some language pragmas and imports:
We now give some “generic instances”. The generic types all have a phantom parameter
x, which makes the instance heads a little more complicated:We now redefine our class
Cto take advantage ofGCNow we can define some instances very easily: