How to define a superclass?
How do I define a superclass in Haskell? My situation is that I have defined a class StringHashed
that maps members to their names as String. I want to implement, en mass, all t
of Show t
, forcing the string name to just return Show t
. Am I correct in saying what is StringHashed
now the superclass of Show? This is what I would like to write:
class StringHashed t where
stringHash :: t -> String
instance Show t => StringHashed t where
stringHash = show
But Haskell is complaining about an invalid instance declaration. I've tried instance StringHashed (Show t)
other syntax tricks as well; nobody worked for me. I also read a suggestion on the GHC wiki which does not provide a solution. This is one . I have a usage problem -XFlexibleInstances
simply because it is not the default. Is there a suitable way to declare a generic instance? Or am I too picky about a system like Haskell?
source to share
Haskell superclasses cannot be added after the fact - they need to be mentioned in the subclass declaration. And defining an instance like you in the question, possibly with extensions, can create subtle overlap problems.
FlexibleInstances
not a problem in itself - it is one of the most innocuous extensions to GHC. The problem is that the GHC instance search method means that
instance Show t => StringHashed t where ...
defines this instance to hold for all types t
- the limitation Show t
is just an afterthought, checked after searching. This way, it will overlap with all other instances you can make, and while extension is allowed for this OverlappingInstances
, it is considered somewhat questionable to use.
However, GHC has a function DefaultSignatures
that is designed for cases similar to yours:
{-# LANGUAGE DefaultSignatures #-}
class StringHashed t where
stringHash :: t -> String
default stringHash :: Show t => t -> String
stringHash = show
instance StringHashed Int
This allows you to write a default value for a method that only works for certain types of instances. Note, however, that you still need to write the actual instance declaration for each type, but its body may be empty.
source to share