($) :: (Int -> Int) -> Int -> Int
-- pruning with 3/3 rules
-- 1 candidates of size 1
-- 1 candidates of size 2
-- tested 2 candidates
f $ x = f x
(.) :: (Int -> Int) -> (Int -> Int) -> Int -> Int
-- pruning with 3/3 rules
-- 1 candidates of size 1
-- 2 candidates of size 2
-- 4 candidates of size 3
-- tested 5 candidates
(f . g) x = f (g x)
flip :: (Int -> Int -> Int) -> Int -> Int -> Int
-- pruning with 3/3 rules
-- 2 candidates of size 1
-- 0 candidates of size 2
-- 4 candidates of size 3
-- tested 5 candidates
flip f x y = f y x
map :: (Int -> Int) -> [Int] -> [Int]
-- pruning with 3/3 rules
-- 2 candidates of size 1
-- 1 candidates of size 2
-- 0 candidates of size 3
-- 2 candidates of size 4
-- 2 candidates of size 5
-- 5 candidates of size 6
-- 7 candidates of size 7
-- tested 13 candidates
map f [] = []
map f (x:xs) = f x:map f xs
fold :: (Int -> Int -> Int) -> Int -> [Int] -> Int
-- pruning with 3/3 rules
-- 1 candidates of size 1
-- 1 candidates of size 2
-- 1 candidates of size 3
-- 6 candidates of size 4
-- 4 candidates of size 5
-- 23 candidates of size 6
-- 19 candidates of size 7
-- tested 38 candidates
fold f x [] = x
fold f x (y:xs) = fold f (f x y) xs
filter :: (Int -> Bool) -> [Int] -> [Int]
-- pruning with 3/3 rules
-- 2 candidates of size 1
-- 1 candidates of size 2
-- 0 candidates of size 3
-- 2 candidates of size 4
-- 0 candidates of size 5
-- 5 candidates of size 6
-- 0 candidates of size 7
-- 15 candidates of size 8
-- 0 candidates of size 9
-- 21 candidates of size 10
-- 0 candidates of size 11
-- 33 candidates of size 12
-- tested 47 candidates
filter f [] = []
filter f (x:xs)
| f x = x:filter f xs
| otherwise = filter f xs