{-# LANGUAGE Haskell2010 #-} 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 Int 0 unfoo :: Foo -> Int unfoo :: Foo -> Int unfoo Foo Bar = Int 0 unfoo Foo Baz = Int 0 unfoo (Quux Foo foo Int n) = Int 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 (Foo Bar, [Foo] xs, Foo Bar)) = [Foo] xs unnorf (Norf (Foo Baz, [Foo] xs, Foo Baz)) = [Foo] -> [Foo] forall a. [a] -> [a] reverse [Foo] xs unnorf Norf _ = [Foo] forall a. HasCallStack => a undefined unnorf' :: Norf -> Int unnorf' :: Norf -> Int unnorf' x :: Norf x@(Norf (f1 :: Foo f1@(Quux Foo _ Int n), [Foo] _, f2 :: Foo f2@(Quux Foo f3 Int _))) = 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 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 a. Num a => [a] -> a 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