import Test.QuickCheck

-- our own implementation of the take function

tak :: Int -> [a] -> [a]
tak n xs | n <= 0 = []
tak n []          = []
tak n (x:xs)      = x : tak (n-1) xs

-- three properties about the length of the result of the take function

-- property for when n lies between 0 and the length of the list
prop_LengthTake :: Int -> [Int] -> Property
prop_LengthTake n xs =
  0 <= n && n <= length xs ==>
    length (tak n xs) == n

-- property for negative n
prop_NegativeTake :: Int -> [Int] -> Property
prop_NegativeTake n xs =
  n < 0 ==>
    length (tak n xs) == 0 

-- property for too big n
prop_TooMuchTake :: Int -> [Int] -> Property
prop_TooMuchTake n xs =
  n > length xs ==>
    length (tak n xs) == length xs 

-- alternative property that avoids computing length xs twice
-- (this is unnecessarily complicated -- avoid such optimizations in testing
-- code!)
prop_TooMuchTake' :: Int -> [Int] -> Property
prop_TooMuchTake' n xs =
  n > len ==>
    length (tak n xs) == len 
 where
  len = length xs