content: {-- RECURSION
  
  The code of this file was stoled with learning purposes
  from learnyouahaskell.com/recursion
  
  --}
  
  maximum' :: (Ord a) => [a] -> a
  maximum' [] = error "maximum of empty list"
  maximum' [x] = x
  maximum' (x:xs)
    | x > maxTail = x
    | otherwise = maxTail
    where maxTail = maximum' xs
  
  -- a clever way
  maximum'' :: (Ord a) => [a] -> a
  maximum'' [] = error "maximum of empty list"
  maximum'' [x] = x
  maximum'' (x:xs) = max x (maximum'' xs)
  
  
  -- replicate a number n x times
  replicate' :: (Num i, Ord i) => i -> a -> [a]
  replicate' n x
     | n <= 0 = []
     | otherwise = x:replicate' (n-1) x
  
  -- replicate 3 5 => [5,5,5]
  
  
  -- take n elements from a list
  take' :: (Num i, Ord i) => i -> [a] -> [a]
  take' n _
    | n <= 0 = []
  take' _ [] = []
  take' n (x:xs) = x : take' (n-1) xs
  
  -- infinite lists
  repeat' :: a -> [a]
  repeat' x = x:repeat' x
  
  zip' :: [a] -> [b] -> [(a,b)]
  zip' _ [] = []
  zip' [] _ = []
  zip' (x:xs) (y:ys) = (x,y):zip' xs ys
  
  
  elem' :: (Eq a) => a -> [a] -> Bool
  elem' a [] = False
  elem' a (x:xs)
    | a == x = True
    | otherwise = a `elem'` xs
  
  
  quicksort :: (Ord a) => [a] -> [a]
  quicksort [] = []
  quicksort (x:xs) =
    let smallerSorted = quicksort [a | a <- xs, a <= x]
        biggerSorted = quicksort [a | a <- xs, a > x]
     in smallerSorted ++ [x] ++ biggerSorted
  