    {-# LANGUAGE Haskell2010 #-}
    module Classes where

    class Foo a where
        bar :: a -> Int
        baz :: Int -> (a, a)

    instance Foo Int where
        bar :: Int -> Int
    bar = Int -> Int
    forall a. a -> a
    id
        baz :: Int -> (Int, Int)
    baz Int
    x = (Int
    x, Int
    x)

    instance Foo [a] where
        bar :: [a] -> Int
    bar = [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length
        baz :: Int -> ([a], [a])
    baz Int
    _ = ([], [])

    class Foo a => Foo' a where
        quux :: (a, a) -> a
        quux (a
    x, a
    y) = [a] -> a
    forall a. Foo' a => [a] -> a
    norf [a
    x, a
    y]

        norf :: [a] -> a
        norf = (a, a) -> a
    forall a. Foo' a => (a, a) -> a
    quux ((a, a) -> a) -> ([a] -> (a, a)) -> [a] -> a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> (a, a)
    forall a. Foo a => Int -> (a, a)
    baz (Int -> (a, a)) -> ([a] -> Int) -> [a] -> (a, a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Int] -> Int
    forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
    sum ([Int] -> Int) -> ([a] -> [Int]) -> [a] -> Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a -> Int) -> [a] -> [Int]
    forall a b. (a -> b) -> [a] -> [b]
    map a -> Int
    forall a. Foo a => a -> Int
    bar

    instance Foo' Int where
        norf :: [Int] -> Int
    norf = [Int] -> Int
    forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
    sum

    instance Foo' [a] where
        quux :: ([a], [a]) -> [a]
    quux = ([a] -> [a] -> [a]) -> ([a], [a]) -> [a]
    forall a b c. (a -> b -> c) -> (a, b) -> c
    uncurry [a] -> [a] -> [a]
    forall a. [a] -> [a] -> [a]
    (++)

    class Plugh p where
        plugh :: p a a -> p b b -> p (a -> b) (b -> a)

    instance Plugh Either where
        plugh :: forall a b. Either a a -> Either b b -> Either (a -> b) (b -> a)
    plugh (Left a
    a) Either b b
    _ = (b -> a) -> Either (a -> b) (b -> a)
    forall a b. b -> Either a b
    Right ((b -> a) -> Either (a -> b) (b -> a))
    -> (b -> a) -> Either (a -> b) (b -> a)
    forall a b. (a -> b) -> a -> b
    $ a -> b -> a
    forall a b. a -> b -> a
    const a
    a
        plugh (Right a
    a) Either b b
    _ = (b -> a) -> Either (a -> b) (b -> a)
    forall a b. b -> Either a b
    Right ((b -> a) -> Either (a -> b) (b -> a))
    -> (b -> a) -> Either (a -> b) (b -> a)
    forall a b. (a -> b) -> a -> b
    $ a -> b -> a
    forall a b. a -> b -> a
    const a
    a
        plugh Either a a
    _ (Left b
    b) = (a -> b) -> Either (a -> b) (b -> a)
    forall a b. a -> Either a b
    Left ((a -> b) -> Either (a -> b) (b -> a))
    -> (a -> b) -> Either (a -> b) (b -> a)
    forall a b. (a -> b) -> a -> b
    $ b -> a -> b
    forall a b. a -> b -> a
    const b
    b
        plugh Either a a
    _ (Right b
    b) = (a -> b) -> Either (a -> b) (b -> a)
    forall a b. a -> Either a b
    Left ((a -> b) -> Either (a -> b) (b -> a))
    -> (a -> b) -> Either (a -> b) (b -> a)
    forall a b. (a -> b) -> a -> b
    $ b -> a -> b
    forall a b. a -> b -> a
    const b
    b