I am trying to write some Haskell code in which there are several data types, each of which can have several implementations. To do this, I define each data type as class, whose methods are the corresponding constructors and selectors, and then implement all operations on the members of this class in terms of the data of the constructors and selectors.
For example, perhaps it Ais a polynomial class (with methods getCoefficientsand makePolynomial) that can have a representation like SparsePolyor DensePolyand Bis a complex class of numbers (with methods getReal, getImagand makeComplex) that can be represented as ComplexCartesianor ComplexPolar.
I reproduced the minimal example below. I have two classes Aand B, each of which has an implementation. I want to make all instances of both classes in instances Numautomatically (this requires type extensions FlexibleInstancesand UndecidableInstances). This works fine when I only have one of Aor B, but when I try to compile with them, I get the following error:
Duplicate instance declarations:
instance [overlap ok] (A a, Num x, Show (a x), Eq (a x)) =>
Num (a x)
-- Defined at test.hs:13:10-56
instance [overlap ok] (B b, Num x, Show (b x), Eq (b x)) =>
Num (b x)
-- Defined at test.hs:27:10-56
I suppose that the message 'duplicate instance declarations' consists in the fact that the type of data could be done as an instance A, and so B. I want to be able to promise the compiler that I will not do this, or perhaps specify a default class to use when the type is an instance of both classes.
(, ?) , ?
:
{-# LANGUAGE FlexibleInstances, UndecidableInstances, OverlappingInstances #-}
class A a where
fa :: a x -> x
ga :: x -> a x
data AImpl x = AImpl x deriving (Eq,Show)
instance A AImpl where
fa (AImpl x) = x
ga x = AImpl x
instance (A a, Num x, Show (a x), Eq (a x)) => Num (a x) where
a1 + a2 = ga (fa a1 + fa a2)
-- other implementations go here
class B b where
fb :: b x -> x
gb :: x -> b x
data BImpl x = BImpl x deriving (Eq,Show)
instance B BImpl where
fb (BImpl x) = x
gb x = BImpl x
instance (B b, Num x, Show (b x), Eq (b x)) => Num (b x) where
-- implementations go here
: , - , . , .