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?

+3


source to share


1 answer


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.

+10


source







All Articles