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