Fun with the types! Resolving multiple instance ads

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

: , - , . , .

+5
2

, "duplicate instance declarations" , A, B. , , , .

. , ,

instance Num (a x)
instance Num (b x)

(. @hammar, ).

.

{-# LANGUAGE FlexibleInstances, FlexibleContexts, UndecidableInstances, OverlappingInstances #-}

data AWitness

data AImpl witness x = AImpl x deriving (Eq,Show)

instance A (AImpl AWitness) where
    fa (AImpl x) = x
    ga x = AImpl x

instance (A (a AWitness), Num x, Show (a AWitness x), Eq (a AWitness x)) => Num (a AWitness x) where
    a1 + a2 = ga (fa a1 + fa a2)

, .

+12

; ,

plusA, minusA :: (A a, Num x) => a x -> a x -> a x

Num , A:

instance A Foo where ...
instance Num x => Num (Foo x) where
    (+) = plusA
    (-) = minusA
+4

All Articles