module Lecture02A where -- Functions over Lists; Classes and Polymorphism; -- more testing -- David Sands 2011-10-31 import Data.List(sort) import Test.QuickCheck -- hide some Prelude functions so we -- can redefine them import Prelude hiding ((++),reverse,drop,take) import qualified Prelude as P((++),reverse,drop,take) -- use the original versions a P.++, P.reverse etc {- Plan: Lists; recursive definitions, polymorphism, classes, quickCheck What are lists? -} -- example list functions from Prelude -- append (++) :: [a] -> [a] -> [a] [] ++ ys = ys (x:xs) ++ ys = x:(xs ++ ys) -- reverse reverse [] = [] reverse (x:xs) = reverse xs ++ [x] -- (inefficient version) rev xs = revinto [] xs where revinto a [] = a revinto a (y:ys) = revinto (y:a) ys -- take, drop drop,take :: Int -> [a] -> [a] take n _ | n <= 0 = [] take _ [] = [] take n (x:xs) = x:take (n-1) xs drop n xs | n <= 0 = xs drop _ [] = [] drop n (x:xs) = drop (n-1) xs -- simple property of take? (==>) prop_take n xs = n >= 0 ==> collect (n > length xs) \$ length (take n xs) <= n prop_takedrop n xs = classify (n <= 0 || n > length xs) "extreme" \$ take n xs ++ drop n xs == xs where types = xs :: [Bool] -- connecting take and drop? qsort [] = [] qsort (x:xs) = qsort smaller ++ [x] ++ qsort bigger where smaller = [y | y <- xs, y < x] bigger = [z | z <- xs, z >= x] prop_qsort xs = sort xs == qsort xs where types = xs :: [Bool] isort [] = [] isort (x:xs) = insert x (isort xs) insert :: Ord a => a -> [a] -> [a] insert x [] = [x] insert x (y:ys) | x <= y = x:y:ys insert x (y:ys) = y:insert x ys prop_insert x xs = insert x (sort xs) == sort (x:xs) -- too similar to definition -- Time permitting: -- Higher-order functions -- filter map and foldr