module L02 where
import Prelude hiding (filter, foldr, head, length, map, product, sum, tail)

add :: (Int, Int) -> Int
add (x, y) = x + y

add' :: Int -> (Int -> Int)
add' x y = x + y
{-
add' = \x -> \y -> x + y
-}

suc = add' 1

{-
myReplicate n x =
  if n <= 0 then []
  else x : myReplicate (n - 1) x
-}
myReplicate n x
  | n <= 0    = []
  | otherwise = x : myReplicate (n - 1) x

{-
range m n =
  if m > n then []
  else m : range (m + 1) n
-}
range m n
  | m > n     = []
  | otherwise = m : range (m + 1) n

{-
mySum xs =
  if null xs then 0
  else head xs + mySum (tail xs)
-}
mySum []     = 0
mySum (x:xs) = x + mySum xs

{-
prod xs =
  if null xs then 1
  else head xs * prod (tail xs)
-}
prod []     = 1
prod (x:xs) = x * prod xs

head (x:_) = x

tail (_:xs) = xs

twice f x = f (f x)

map :: (a -> b) -> [a] -> [b]
map f []     = []
map f (x:xs) = f x : map f xs

filter :: (a -> Bool) -> [a] -> [a]
filter p []   = []
filter p (x:xs)
  | p x       = x : filter p xs
  | otherwise = filter p xs

foldr :: (a -> b -> b) -> b -> [a] -> b
foldr f b []     = b
foldr f b (x:xs) = x `f` (foldr f b xs)

sum = foldr (+) 0

product = foldr (*) 1

length = foldr (const (+1)) 0