
This is my first post here, so Hello everyone! In haskell it is possible to express a constraint "if 'a' and 'b' are instance of 'AB' then 'a' is instance of 'A' and 'b' is instance of 'B'": class (A a, B b) => AB a b ... Is it possible to express the converse - "if 'a' is instance of 'A' and 'b' is instance of 'B' then 'a' and 'b' are instance of 'AB'"? I want to create a list of shapes that can be tested for intersection. I think that possibility of expressing such constraints would allow to doing this in a "Object Oriented" way: data Circle = Circle { ... } data Square = Square { ... } class Shape a class Intersect a b where intersect :: a -> b -> Bool -- pseudo haskell - "If 'a' is instance of 'Shape' and 'b' is instance of 'Shape' then 'a' and 'b' are instance of 'Intersect'" -- maybe some type hackery allows to express this? constraint Shape a, Shape b => Intersect a b instance Shape Circle instance Shape Square instance Intersect Circle Circle ... instance Intersect Circle Square ... ... data ShapeBox = forall a. Shape a => ShapeBox a foo = let x:y:_ = [ShapeBox Circle { ... }, ShapeBox Square { ... }, ...] in intersect x y -- this should work because we know for sure that there is an instance of Intersect for type of 'x' and type of 'y' Is such idea already described somewhere?