{-# 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