-- | Working with List -- Examples to illustrate pattern matching, recursion and testing for lists -- Functional Programming course 2016. -- Thomas Hallgren {- This started out as a skeleton, the definitions were filled in during the lecture. -} import Prelude hiding ((++),reverse,take,drop,splitAt,zip,unzip) import qualified Prelude import Test.QuickCheck (++) :: [a] -> [a] -> [a] [] ++ ys = ys xs ++ [] = xs (x:xs) ++ ys = x:(xs++ys) cons x xs = x:xs snoc xs x = xs++[x] reverse :: [a] -> [a] reverse [] = [] reverse (x:xs) = reverse xs ++ [x] -- complexity? how to make it more efficient? -- | Take the first n elements of a list take :: Int -> [a] -> [a] take n _ | n<=0 = [] take _ [] = [] take n (x:xs) = x:take (n-1) xs prop_take n xs = length (take n xs) == max 0 (min n (length xs)) -- | Discard the first n elements of a list drop :: Int -> [a] -> [a] drop n xs| n<=0 = xs drop _ [] = [] drop n (x:xs) = drop (n-1) xs prop_take_drop n xs = take n xs ++ drop n xs == (xs::[Int]) nonprop_take_drop n xs = drop n xs ++ take n xs == (xs::[Int]) -- | splitAt n xs = (take n xs,drop n xs) --splitAt :: Int -> [a] -> ([a],[a]) -- | Combine a pair of list into a list of pairs zip :: [a] -> [b] -> [(a,b)] zip (x:xs) (y:ys) = (x,y):zip xs ys zip _ _ = [] -- | Split a list of pairs into a pair of lists unzip :: [(a,b)] -> ([a],[b]) unzip [] = ([],[]) unzip ((x,y):xys) = let (xs,ys) = unzip xys in (x:xs,y:ys) prop_zip_unzip :: (Eq a,Num a) => [(a,a)] -> Bool prop_zip_unzip xys = let (xs,ys) = unzip xys in zip xs ys == xys prop_unzip_zip xs ys = unzip (zip xs ys) == (xs,ys) -- | "Quicksort" qsort :: Ord a => [a] -> [a] qsort [] = [] qsort (x:xs) = qsort [y|y<-xs,y=x] -- * Filled in after the lecture -- | insert a new element at the right position in a sorted list insert :: Ord a => a -> [a] -> [a] insert x [] = [x] insert x (x1:xs) | x [a] -> [a] isort [] = [] isort (x:xs) = insert x (isort xs) prop_qsort xs = qsort xs == isort (xs::[Int])