Show, Eq not necessary for Num [Was: Revamping the numeric c

Elke Kasimir
Thu, 08 Feb 2001 15:11:21 +0100 (CET)

On 07-Feb-2001 Patrik Jansson wrote:

(interesting stuff deleted)

> As far as I remember from the earlier discussion, the only really visible
> reason for Show, Eq to be superclasses of Num is that class contexts are
> simpler when (as is often the case) numeric operations, equality and show
> are used in some context.
> f :: Num a => a -> String  -- currently
> f a = show (a+a==2*a)
> If Show, Eq, Num were uncoupled this would be
> f :: (Show a, Eq a, Num a) => a -> String
> But I think I could live with that. (In fact, I rather like it.)

Basically I'm too.

However, what is missing for me is something like:

type Comfortable a = (Show a, Eq a, Num a) => a


class (Show a, Read a, Eq a) => Comfortable a
instance (Show a, Read a, Eq a) => Comfortable a 

I think here is a point where a general flaw of class hierachies as a mean
of software design becomes obvious, which consists of forcing the programmer
to arbitrarily prefer few generalizations to all others in a global, 
context-independent design decision.

The oo community (being the source of all the evil...) usually relies on the 
rather problematic ontological assumption that, at least from a certain point
of view (problem domain, design, implemention), the relevant concepts form in
a natural way a kind a generalization hierarchy, and that this generalization 
provides a natural way to design the software (in our case, determine the
type system in some a-priory fashion).

Considering the fact that a concept, for which (given a certain point of view)  
n elementary predicates hold a-priory, n! possible generalizations exist 
a-priory, this assumption can be questioned. 

In contrary to the given assumption, I have made the experience that, when 
trying to classify concepts,  even a light shift in the situation being 
under consideration can lead to a severe change in what appears to be the 
"natural" classification.  

Besides this, as is apparent in Show a => Num a, it is not always a priory 
generalizations that are really needed. Instead, the things must be fit
into the current point of view with a bit force, thus changing 
concepts or even inventing new ones.

(For example, in the oo community, which likes (or is forced?) to "ontologize" 
relationships into "objects", has invented "factories" for different things, 
ranging from GUI border frames to database connection handles. 
Behind such an at first glance totally arbitary conceptualization might stand
a more rational concept, for example applying a certain library design principle
called "factory" to different types of things. However one can't always wait 
until the rationale behind a certain solution is clearly recognized.)
In my experience, both class membership and generalization relationships are 
often needed locally and post hoc, and they sometimes even express empirical 
(a-posteriory) relations between concepts instead of true analytical (a-priory) 
generalization relationships.

As a consequence, for my opinion, programming languages should make it
possible and easy to employ post-hoc and local class membership declarations and
post-hoc and local class hierarchy declarations (or even re-organizations).

There will of course be situations where a global a-priory declaration of 
generalization nevertheless still make completely sense.

For Haskell, I could imagine (without having having much thought about) in 
addition to the things mentioned in the beginning, several things making 
supporting the  "locally, fast and easy", including a mean to define classes 
with implied memberships, for example declarations saying that "Foo is the class
of all types in scope for which somefoo :: ... is defined", or declarations  
saying that "class Num is locally restricted to all instances of global Num 
which also belong to Eq".


Elke Kasimir
Skalitzer Str. 79
10997 Berlin (Germany)
fon:  +49 (030) 612 852 16
see: <>

for pgp public key see: