data A = True' | False'
  deriving Show

foo :: A -> Integer
foo True'  = 1
foo False' = 0

data P3 = P Bool A -- P (Bool x A)

data BigP = P1 Bool A | P2 Integer
  deriving Show

bar :: BigP -> Integer
bar (P1 _ _) = 1
bar (P2 _) = 2

int_plus_3 :: Integer -> Integer
int_plus_3 n = n + 3

-- examples
comp :: BigP -> Integer
comp = int_plus_3 . bar
-- same as: int_plus_3 $ bar $ P2 10

double_arg :: Integer -> Integer -> Integer
double_arg a b = a + b

partially_applied :: Integer -> Integer
partially_applied = double_arg 7


func_arg :: (Integer -> Integer) -> Integer -> Integer
func_arg f b = f b


main :: IO ()
main = putStrLn "Hello world"