class A a where basicA :: a -> Bool nextA :: a -> StupidA basicA _ = True nextA a = StupidA a data StupidA = forall a . A a => StupidA a instance A StupidA where basicA (StupidA a) = basicA a nextA (StupidA a) = StupidA (nextA a) data WrappedA = forall a . A a => WrappedA a instance A WrappedA where basicA _ = False nextA (WrappedA a) = StupidA a data A1 = A1 instance A A1 class B b where basicB :: b -> Bool nextB :: b -> StupidB basicB _ = True nextB b = StupidB b data StupidB = forall b . B b => StupidB b instance B StupidB where basicB (StupidB b) = basicB b nextB (StupidB b) = StupidB (nextB b) data WrappedB = forall b . B b => WrappedB b instance B WrappedB where basicB _ = False nextB (WrappedB b) = StupidB b data B1 = B1 instance B B1 toBool :: (A a, B b) => a -> b -> Bool toBool a b | basicA a && basicB b = True | basicA a || basicB b = False | otherwise = toBool (nextA a) (nextB b) main = return ()