module Constructors where data Foo = Bar | Baz | Quux Foo Int newtype Norf = Norf (Foo, [Foo], Foo) bar, baz, quux :: Foo bar :: Foo bar = Foo Bar baz :: Foo baz = Foo Baz quux :: Foo quux = Foo -> Int -> Foo Quux Foo quux 0 unfoo :: Foo -> Int unfoo :: Foo -> Int unfoo Bar = 0 unfoo Baz = 0 unfoo (Quux foo :: Foo foo n :: Int n) = 42 Int -> Int -> Int forall a. Num a => a -> a -> a * Int n Int -> Int -> Int forall a. Num a => a -> a -> a + Foo -> Int unfoo Foo foo unnorf :: Norf -> [Foo] unnorf :: Norf -> [Foo] unnorf (Norf (Bar, xs :: [Foo] xs, Bar)) = [Foo] xs unnorf (Norf (Baz, xs :: [Foo] xs, Baz)) = [Foo] -> [Foo] forall a. [a] -> [a] reverse [Foo] xs unnorf _ = [Foo] forall a. HasCallStack => a undefined unnorf' :: Norf -> Int unnorf' :: Norf -> Int unnorf' x :: Norf x@(Norf (f1 :: Foo f1@(Quux _ n :: Int n), _, f2 :: Foo f2@(Quux f3 :: Foo f3 _))) = Int x' Int -> Int -> Int forall a. Num a => a -> a -> a + Int n Int -> Int -> Int forall a. Num a => a -> a -> a * Foo -> Int unfoo Foo f1 Int -> Int -> Int forall a. Num a => a -> a -> a + Foo -> Int aux Foo f3 where aux :: Foo -> Int aux fx :: Foo fx = Foo -> Int unfoo Foo f2 Int -> Int -> Int forall a. Num a => a -> a -> a * Foo -> Int unfoo Foo fx Int -> Int -> Int forall a. Num a => a -> a -> a * Foo -> Int unfoo Foo f3 x' :: Int x' = [Int] -> Int forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a sum ([Int] -> Int) -> (Norf -> [Int]) -> Norf -> Int forall b c a. (b -> c) -> (a -> b) -> a -> c . (Foo -> Int) -> [Foo] -> [Int] forall a b. (a -> b) -> [a] -> [b] map Foo -> Int unfoo ([Foo] -> [Int]) -> (Norf -> [Foo]) -> Norf -> [Int] forall b c a. (b -> c) -> (a -> b) -> a -> c . Norf -> [Foo] unnorf (Norf -> Int) -> Norf -> Int forall a b. (a -> b) -> a -> b $ Norf x