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