[Haskell-beginners] How to manage typeclass hierarchies and instances?

Stuart Hungerford stuart.hungerford at gmail.com
Sat Feb 21 21:15:53 UTC 2015


>> -- 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


More information about the Beginners mailing list