
Felipe Lessa wrote:
class Shape a where ....whatever....
class (Shape a, Shape b) => Intersectable a b where intersect :: a -> b -> Bool
This looks nice at first sight, but is it usefull in practice? I can somehow express the type "any shape wich is intersectable with a given other shape", but it is a pain: data Intersectable a = forall b . Intersectable a b => Intersectable b instance Intersectable a (Intersectable b) where intersect a (Intersectable b) = intersect a b Now consider I write another binary function as a type class: class (Shape a, Shape b) => Containment a b where contains :: a -> b -> Bool data Containment a = forall b . Containment a b => Containment b instance Containment a (Containment b) where contains a (Containment b) = contains a b I cannot combine these types to express "any shape wich is intersectable and can be united with a given other shape" without writing another existiential wrapper. I cannot express "a list of pairwise intersectable shapes" either. Things get even worse if we consider a different definition of intersect: class (Shape a, Shape b, Shape c) => Intersect a b c | a b -> c where intersect :: a -> b -> c My conclusion: To make Haskell a better OO language then current OO languages, we need either first-class typeclasses (to quantify over the classes an existential wrapped value supports) or inference of existential wrappers (to infer complicated wrappers automatically). (Since it's not the goal of Haskell to be any OO language at all this may not be a problem) Tillmann