Programmieren in Haskell Programmieren mit Listen II Peter Steffen Universität Bielefeld Technische Fakultät 21.11.2008 1 Programmieren in Haskell Was wir heute machen Von eigenen Listen zu eingebauten Eine Sortierfunktion Nützliche Listenfunktionen Listenbeschreibungen Primzahlen Noch eine Sortierfunktion 2 Programmieren in Haskell Von eigenen Listen zu eingebauten data List a = Nil | Cons a (List a) data [a] = [] | (a:[a]) -- Pseudocode Nil :: List a Cons 1 (Cons 2 (Cons 3 Nil)) :: Num a => List a Cons "hallo" (Cons "welt" Nil) :: List [Char] [] :: [a] 1:2:3:[] :: Num a => [a] "hallo":"welt":[] :: [[Char]] -- "normale" infix-Schreibweise -- ebenso (:) 1 ((:) 2 ((:) 3 [])) :: Num a => [a] 3 -- prefix-Schreibweise! Programmieren in Haskell Von eigenen Listen zu eingebauten data List a = Nil | Cons a (List a) data [a] = [] | (a:[a]) -- Pseudocode Nil :: List a Cons 1 (Cons 2 (Cons 3 Nil)) :: Num a => List a Cons "hallo" (Cons "welt" Nil) :: List [Char] [] :: [a] 1:2:3:[] :: Num a => [a] "hallo":"welt":[] :: [[Char]] -- "normale" infix-Schreibweise -- ebenso (:) 1 ((:) 2 ((:) 3 [])) :: Num a => [a] 3 -- prefix-Schreibweise! Programmieren in Haskell Von eigenen Listen zu eingebauten data List a = Nil | Cons a (List a) data [a] = [] | (a:[a]) -- Pseudocode Nil :: List a Cons 1 (Cons 2 (Cons 3 Nil)) :: Num a => List a Cons "hallo" (Cons "welt" Nil) :: List [Char] [] :: [a] 1:2:3:[] :: Num a => [a] "hallo":"welt":[] :: [[Char]] -- "normale" infix-Schreibweise -- ebenso (:) 1 ((:) 2 ((:) 3 [])) :: Num a => [a] 3 -- prefix-Schreibweise! Programmieren in Haskell Sortieren durch Einfügen isort :: Ord a => [a] -> [a] isort [] = [] isort (x:xs) = insert x (isort xs) where insert x [] = [x] insert x (y:ys) | x <= y = x:y:ys | x > y = y:(insert x ys) 4 Programmieren in Haskell Nützliche Listenfunktionen head’ :: [a] -> a head’ [] = error "head’ not defined for empty lists" head’ (x:xs) = x tail’ :: [a] -> [a] tail’ [] = error "tail’ not defined for empty lists" tail’ (x:xs) = xs 5 Programmieren in Haskell Nützliche Listenfunktionen length’ :: Num a => [b] -> a length’ [] = 0 length’ (x:xs) = 1 + length’ xs sum’ :: Num a => [a] -> a sum’ [] = 0 sum’ (x:xs) = x + sum’ xs product’ :: Num a => [a] -> a product’ [] = 1 product’ (x:xs) = x * product’ xs 6 Programmieren in Haskell Nützliche Listenfunktionen enumFromTo’ :: (Enum a, Ord a) => a -> a -> [a] enumFromTo’ a b | a > b = [] | a == b = [a] | a < b = a:(enumFromTo’ (succ a) b) factorial’ :: Integral a => a -> a factorial’ n | n < 0 = error "factorial’ not defined for negative values" | otherwise = product’ (enumFromTo’ 1 n) 7 Programmieren in Haskell Nützliche Listenfunktionen append’ :: [a] -> [a] -> [a] append’ [] ys = ys append’ (x:xs) ys = x:(append’ xs ys) reverse’Slow :: [a] -> [a] reverse’Slow [] = [] reverse’Slow (x:xs) = append’ (reverse’Slow xs) [x] schneller: reverse’ :: [a] -> [a] reverse’ xs = rev [] xs where rev as [] = as rev as (x:xs) = rev (x:as) xs 8 Programmieren in Haskell Nützliche Listenfunktionen take’ take’ | n take’ take’ | n | n 9 :: Integral a => a -> [b] -> [b] n xs < 0 = error "take’ not defined for negative values" n [] = [] n (x:xs) == 0 = [] > 0 = x:(take’ (n-1) xs) Programmieren in Haskell Nützliche Listenfunktionen drop’ drop’ | n drop’ drop’ | n | n 10 :: Integral a => a -> [b] -> [b] n xs < 0 = error "drop’ not defined for negative values" n [] = [] n (x:xs) == 0 = x:xs > 0 = drop’ (n-1) xs Programmieren in Haskell Nützliche Listenfunktionen 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 11 Programmieren in Haskell Nützliche Listenfunktionen concat’ :: [[a]] -> [a] concat’ [] = [] concat’ (xs:xss) = append’ xs (concat’ xss) 12 Programmieren in Haskell Listen-Zucker [1 ..] Liste der positiven, ganzen Zahlen [1 .. 99] Liste der positiven, ganzen Zahlen bis einschließlich 99 [1, 3 ..] Liste der ungeraden, positiven Zahlen [1, 3 .. 99] Liste der ungeraden, positiven Zahlen bis einschließlich 99 13 Programmieren in Haskell Listenbeschreibungen squares = [n*n | n <- [0..99]] squares2 = [n*n | n <- [0..99], n ‘mod‘ 2 == 0] map f xs = [f a | a <- xs] a ‘elem‘ xs = or [a == b | b <- xs] 14 Programmieren in Haskell Primzahlen primesSlow :: Integral a => [a] primesSlow = [n | n <- [2..], divisors n == [1,n]] where divisors :: Integral a => a -> [a] divisors n = [d | d <- [1..n], n ‘mod‘ d == 0] 15 Programmieren in Haskell Sieb des Eratosthenes primes :: Integral a => [a] primes = sieve [2..] where sieve :: Integral a => [a] -> [a] sieve (a:xs) = a:sieve [n | n <- xs, n ‘mod‘ a /= 0] 16 Programmieren in Haskell Quicksort qsort :: Ord a => [a] -> [a] qsort [] = [] qsort (a:xs) = qsort [b | b <- xs, b < a] ++ [a] ++ qsort [b | b <- xs, b >= a] 17 Programmieren in Haskell