[Haskell-cafe] Inheritance and Wrappers

Brandon Moore brandon_m_moore at yahoo.com
Thu Feb 3 03:35:27 CET 2011

>OK, what about this as a use case then. I want to create a type class 'Term' 
>with only one function in it. The function returns a 'termTag' which labels the 

>"kind" of a value in a DSL.  
>class Term a where
>   termTag :: a -> String
>A user of this type-class can happily provide an instance without any other type 
>class requirement. However, I want those types which are instances of Data to be 
>an instance of Term automatically. On top of that, I don't want to stop the user 
>from creating a special instance for their data type.
>I want to be able to write the following instance to accomplish that:
>instance Data t => Term t where
>    termTag = show . toConstr

A much more predictable option is to provide this default implementation
as a function

termTagData :: (Data t) => (t -> String)

and let the library clients use it in their instances if the behavior is fine:

instance Term MyT where
  termTag = termTagData

>And if the user wants to write a more specific instance, they should be welcome 

>to do so:
>instance Term UserDT where
>    termTag (...) = ...
>I am not very much interested in the technical details about how things 
>currently are, I am more interested in a discussion about why (if?) this would 
>be considered a design flaw?

Here's one thing to consider:

Can you write a function

f :: (Data a) => a -> String
f x = termTag x

It would seem the Data a => Term a instance justifies
this function, and it will always use the default instance.

Now, what happens if "f" is applied to a value of some type
T which is an instance of Data, but has a custom Term instance?



More information about the Haskell-Cafe mailing list