The package constructive-algebra allows you to define instances of algebraic modules (like vectorial spaces but using a ring where a field was required)
This is my try at defining a module:
{-# LANGUAGE MultiParamTypeClasses, TypeSynonymInstances #-}
module A where
import Algebra.Structures.Module
import Algebra.Structures.CommutativeRing
import Algebra.Structures.Group
newtype A = A [(Integer,String)]
instance Group A where
(A a) <+> (A b) = A $ a ++ b
zero = A []
neg (A a) = A $ [((-k),c) | (k,c) <- a]
instance Module Integer A where
r *> (A as) = A [(r <*> k,c) | (k,c) <- as]
It fails by:
A.hs:15:10:
Overlapping instances for Group A
arising from the superclasses of an instance declaration
Matching instances:
instance Ring a => Group a -- Defined in Algebra.Structures.Group
instance Group A -- Defined at A.hs:9:10-16
In the instance declaration for `Module Integer A'
A.hs:15:10:
No instance for (Ring A)
arising from the superclasses of an instance declaration
Possible fix: add an instance declaration for (Ring A)
In the instance declaration for `Module Integer A'
Failed, modules loaded: none.
If I comment the Group instance out, then:
A.hs:16:10:
No instance for (Ring A)
arising from the superclasses of an instance declaration
Possible fix: add an instance declaration for (Ring A)
In the instance declaration for `Module Integer A'
Failed, modules loaded: none.
I read this as requiring an instance of Ring A to have Module Integer A which doesn’t make sense and is not required in the class definition:
class (CommutativeRing r, AbelianGroup m) => Module r m where
-- | Scalar multiplication.
(*>) :: r -> m -> m
Could you explain this?
The package contains an
The instance head
amatches every type expression, so any instance with any other type expression will overlap. That overlap only causes an error if such an instance is actually used somewhere. In your module, you use the instance inThe
Moduleclass has anAbelianGroupconstraint on themparameter¹. That implies aGroupconstraint. So for this instance, theGroupinstance ofAmust be looked up. The compiler finds two matching instances.That is the first reported error.
The next is because the compiler tries to find an
AbelianGroupinstance forA. The only instance the compiler knows about at that point isso it tries to find the
instance Ring A where ..., but of course there isn’t one.Instead of commenting out the
instance Group A where ..., you should add an(even if it’s a lie, we just want to make it compile at the moment) and also add
OverlappingInstancesto the{-# LANGUAGE #-}pragma.With
OverlappingInstances, the most specific matching instance is chosen, so it does what you want here.¹ By the way, your
Aisn’t an instance ofAbelianGroupand rightfully can’t be unless order is irrelevant in the[(Integer,String)]list.