module ABC where newtype A = A () newtype B = B () newtype C = C () data T = TA A | TB B | TC C class TClass a where f1 :: a -> a -> a f2 :: a -> a -> a f3 :: a -> a -> a instance TClass A where f1 (A _) (A _) = A () f2 (A _) (A _) = A () f3 (A _) (A _) = A () instance TClass B where f1 (B _) (B _) = B () f2 (B _) (B _) = B () f3 (B _) (B _) = B () instance TClass C where f1 (C _) (C _) = C () f2 (C _) (C _) = C () f3 (C _) (C _) = C () apply :: TClass a => (a -> a -> a) -> T -> T -> T apply fn x y = case (x, y) of (TA x, TA y) -> TA (fn x y) (TB x, TB y) -> TB (fn x y) (TC x, TC y) -> TC (fn x y) _ -> error "T constructors do not match" {--------------------------------------------------------------------------------------------------- [1 of 1] Compiling ABC ( ABC.hs, ABC.o ) ABC.hs:29:25: Couldn't match type `A' with `C' In the return type of a call of `fn' In the first argument of `TA', namely `(fn x y)' In the expression: TA (fn x y) ABC.hs:29:28: Couldn't match type `A' with `C' In the first argument of `fn', namely `x' In the first argument of `TA', namely `(fn x y)' In the expression: TA (fn x y) ABC.hs:29:30: Couldn't match type `A' with `C' In the second argument of `fn', namely `y' In the first argument of `TA', namely `(fn x y)' In the expression: TA (fn x y) ABC.hs:30:25: Couldn't match type `B' with `C' In the return type of a call of `fn' In the first argument of `TB', namely `(fn x y)' In the expression: TB (fn x y) ABC.hs:30:28: Couldn't match type `B' with `C' In the first argument of `fn', namely `x' In the first argument of `TB', namely `(fn x y)' In the expression: TB (fn x y) ABC.hs:30:30: Couldn't match type `B' with `C' In the second argument of `fn', namely `y' In the first argument of `TB', namely `(fn x y)' In the expression: TB (fn x y) ---------------------------------------------------------------------------------------------------}