data Foo1 a = Foo1 a data Foo2 a = Foo2 a foo1 :: Foo1 a -> a foo1 (Foo1 x) = x foo2 :: Foo2 a -> a foo2 (Foo2 x) = x class Makeable s where make :: a -> s a instance Makeable Foo1 where make = Foo1 instance Makeable Foo2 where make = Foo2 class (Makeable f) => Foo f where foo :: f a -> a class (Makeable b) => Bar b where bar :: b a -> a class (Makeable b) => Baz b where baz :: b a -> a class (Makeable b) => Bim b where bim :: b a -> a instance Foo Foo1 where foo = foo1 instance Bar Foo2 where bar = foo2 instance (Bar b) => Baz b where baz = bar instance Bim Foo1 where bim = foo1 instance (Baz b) => Bim b where bim = baz doFoo1 (Foo1 x) = x doFoo2 (Foo2 x) = x useBim :: Bim b => (forall a. b a -> a) -> a -> [a] useBim doit x = [doit (make x), bim (make x :: Foo1 a)] main = "OK" -- "OK"