Context in data and class declarations (was haskell programming guidelines)

Hi - In http://www.informatik.uni-bremen.de/agbkb/forschung/formal_methods/CoFI/hets... one of the recommendations states: "Don't put class constraints on a data type, constraints belong only to the functions that manipulate the data." This made me think: what on earth was the point of allowing contexts on a data declaration in the first place? I've always found it a confusing feature of Haskell since you in any case need to "repeat" all the (relevant) constraints when declaring the type of any function that manipulates the data. There does not appear to be any sensible reason for requiring the constraints for constructor functions, because the constructor functions would never ever need to use them... Therefore would it be a good idea to get rid of this feature altogether? Another confusing thing is the use of the word "inheritance" in tutorials/books about class declarations. Unlike object oriented languages, where a class or interface gets all the methods of its ancestor classes/interfaces in addition to some new methods declared at that level, each Haskell type class is completely independent of any other type class. For example, the class Ord contains methods for (<) (<=) (>=) (>) max min but does not contain the methods of Eq even though this confusing word "inheritance" or "superclass" would imply that it should. Ord does *not* "inherit" anything at all - the meaning of the Eq context in the class declaration is just that we will need the Eq dictionary in addition to the Ord dictionary when calling any of Ord's methods. Thus I propose that the contexts don't really have any place in a class declaration either ie class Eq a => Ord a where (<), (<=), ... :: would be better written as: class Ord a where (<), (<=), .... :: Eq a => a->a->Bool so the language wouldn't be so confusing to learn. Classes are after all extremely simple! :-) Regards, Brian.

Brian Hulley wrote:
<snip> Another confusing thing is the use of the word "inheritance" in tutorials/books about class declarations. Unlike object oriented languages, where a class or interface gets all the methods of its ancestor classes/interfaces in addition to some new methods declared at that level, each Haskell type class is completely independent of any other type class. For example, the class Ord contains methods for (<) (<=) (>=) (>) max min but does not contain the methods of Eq even though this confusing word "inheritance" or "superclass" would imply that it should. Ord does *not* "inherit" anything at all - the meaning of the Eq context in the class declaration is just that we will need the Eq dictionary in addition to the Ord dictionary when calling any of Ord's methods. Thus I propose that the contexts don't really have any place in a class declaration either ie
class Eq a => Ord a where (<), (<=), ... ::
would be better written as:
class Ord a where (<), (<=), .... :: Eq a => a->a->Bool
so the language wouldn't be so confusing to learn. Classes are after all extremely simple! :-)
Sorry folks I've got all this completely wrong! ;-) It seems the Ord dictionary does in fact contain the Eq dictionary since the following examples compile: test :: Ord a => a->a->Bool test x y = x <= y test2 :: Ord a => a->a->Bool test2 x y = x == y I think what confused me was that although the Ord dictionary contains the methods for Eq, you cannot override the Eq methods in an instance declaration for Ord - you have to use two instance declarations to achieve this, one for Ord and one for Eq, so as far as instance declarations are concerned, the type classes are separate, but the dictionaries are not. Regards, Brian.
participants (1)
-
Brian Hulley