
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 or 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. --- Elke Kasimir Skalitzer Str. 79 10997 Berlin (Germany) fon: +49 (030) 612 852 16 mail: elke.kasimir@catmint.de> see: http://www.catmint.de/elke for pgp public key see: http://www.catmint.de/elke/pgp_signature.html