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?