
-- in Semigroup.hs
class Semigroup a where (|.|) :: a -> a -> a
instance Semigroup Integer where (|.|) = (+)
-- In Monoid.hs
class (Semigroup a) => Monoid a where identity :: a
instance Monoid Integer where identity = 0
-- In Group.hs
class (Monoid a) => Group a where inverse :: a -> a
instance Group Integer where (|.|) = (+) identity = 0 inverse = (-)
In Group.hs I'm trying to create an (additive) group instance for Integer values but GHC complains that (|.|) and identity are not "visible" typeclass methods.
You only get one instance per type, so the Semigroup/Monoid instances for Integer are "set in stone." When you "import Semigroup" and "import Monoid", those instances come into scope. So in Group.hs, '|.|' and 'identity' are already defined for Integer. All you need is,
instance Group Integer where inverse = negate
Thanks for that insight. Ignoring the instance issue for a minute, suppose I wanted to define a typeclass Additive where I'd like to set default implementations for the methods: class (Num a, Group a) => Additive a where (|.|) = (+) -- etc... In this situation GHC says (|.|) is not a visible method. If I add a type declaration for (|.|) am I effectively "shadowing" the method from Semigroup with a new method rather than supplying a default implementation? Thanks, Stu