module Classes where class Foo a where bar :: a -> Int baz :: Int -> (a, a) instance Foo Int where bar = id baz x = (x, x) instance Foo [a] where bar = length baz _ = ([], []) class Foo a => Foo' a where quux :: (a, a) -> a quux (x, y) = norf [x, y] norf :: [a] -> a norf = quux . baz . sum . map bar instance Foo' Int where norf = sum instance Foo' [a] where quux = uncurry (++) class Plugh p where plugh :: p a a -> p b b -> p (a -> b) (b -> a) instance Plugh Either where plugh (Left a) _ = Right $ const a plugh (Right a) _ = Right $ const a plugh _ (Left b) = Left $ const b plugh _ (Right b) = Left $ const b