III.6 Funktionale Programmiertechniken - 1 - 6. Funktionale Programmiertechniken: Funktionen höherer Ordnung 5. Typen und Datenstrukturen 4. Muster (Patterns) 3. Ausdrücke 2. Deklarationen 1. Prinzipien der funktionalen Programmierung (a -> b) -> (a -> c) Ergebnis vom Typ: III.6 Funktionale Programmiertechniken - 2 - (b -> c) Argument vom Typ: comp f g = \x -> f (g x) comp :: (b -> c) -> (a -> b) -> (a -> c) Funktionen höherer Ordnung: comp plus :: Int -> Int -> Int plus x y = x + y curry III.6 Funktionale Programmiertechniken - 3 - uncurry :: (a -> b -> c) -> (a,b) -> c uncurry g = f where f (x,y) = g x y curry :: ((a,b) -> c) -> a -> b -> c curry f = g where g x y = f (x,y) uncurry plus :: (Int, Int) -> Int plus (x, y) = x + y Funktionen höherer Ordnung: curry f :: [a] -> [b] f [] = [] f (x:xs) = g x : f xs III.6 Funktionale Programmiertechniken - 4 - map :: (a -> b) -> [a] -> [b] map g [] = [] map g (x:xs) = g x : map g xs suclist [ x 1 ,..., x n ] = [ suc x 1 ,..., suc x n ] sqrtlist [ x 1 ,..., x n ] = [sqrt x 1 ,..., sqrt x n] fmap g [ x 1 ,..., x n ] = [ g x 1 ,..., g x n ] Float -> [Float] sqrtlist :: [Float] Float sqrtlist [] = [] sqrtlist (x:xs) = sqrt x : sqrtlist xs suclist :: [Int] Int -> [Int] Int suclist [] = [] suclist (x:xs) = suc x : suclist xs Funktionen höherer Ordnung: map f :: [a] -> [b] f [] = [] f (x:xs) = g x : f xs III.6 Funktionale Programmiertechniken - 5 - map :: (a -> b) -> [a] -> [b] map g [] = [] map g (x:xs) = g x : map g xs suclist [ x 1 ,..., x n ] = [ suc x 1 ,..., suc x n ] sqrtlist [ x 1 ,..., x n ] = [sqrt x 1 ,..., sqrt x n] fmap g [ x 1 ,..., x n ] = [ g x 1 ,..., g x n ] sqrtlist :: [Float] [Float [Float] Float] -> [Float] sqrtlist=[] suclist map sqrt = [] sqrtlist (x:xs) = sqrt x : sqrtlist xs suclist :: [ [Int] [Int] Int] -> [ Int] suclist = []map suc= [] suclist (x:xs) = suc x : suclist xs Funktionen höherer Ordnung: map III.6 Funktionale Programmiertechniken - 6 - filter :: (a -> Bool) -> [a] -> [a] filter g [] = [] filter g (x:xs) | g x = x : filter g xs | otherwise = filter g xs f :: [ a ] -> [ a ] f [] = [] f (x:xs) | g x = x : f xs | otherwise = f xs dropUpper :: [ Char ] -> [ Char ] dropUpper [] = [] dropUpper (x:xs) | isLower x = x : dropUpper xs | otherwise = dropUpper xs dropEven :: [ Int ] -> [ Int ] dropEven [] = [] dropEven (x:xs) | odd x = x : dropEven xs | otherwise = dropEven xs Funktionen höherer Ordnung: filter III.6 Funktionale Programmiertechniken - 7 - filter :: (a -> Bool) -> [a] -> [a] filter g [] = [] filter g (x:xs) | g x = x : filter g xs | otherwise = filter g xs f :: [ a ] -> [ a ] f [] = [] f (x:xs) | g x = x : f xs | otherwise = f xs dropUpper :: [ Char ] -> [ Char ] dropUpper :: [ Char ] -> [ Char ] [] = [] dropUpper = filter (x:xs) | isLower x = x : dropUpper xs | otherwise = dropUpper xs dropEven :: [ Int ] -> [ Int ] [] [ = Int [] ] -> [ Int ] dropEven :: (x:xs) | odd x = x : dropEven xs dropEven = filter | otherwise = dropEven xs Funktionen höherer Ordnung: filter III.6 Funktionale Programmiertechniken - 8 - 6. Funktionale Programmiertechniken: Unendliche Datenobjekte 5. Typen und Datenstrukturen 4. Muster (Patterns) 3. Ausdrücke 2. Deklarationen 1. Prinzipien der funktionalen Programmierung Terminiert nicht! Terminiert nicht! mult infinity 0 0 * infinity III.6 Funktionale Programmiertechniken - 9 - = 0 mult 0 infinity mult :: Int -> Int -> Int mult 0 y = 0 mult (x+1) y = y + mult x y infinity :: Int infinity = infinity + 1 Nicht-strikte Auswertung take take take take :: Int -> [a] 0 _ = _ [] = (n+1)(x:xs) = 5 : take 1 (from 6) 5 : take 1 (6 : from 7) 5 : 6 : take 0 (from 7) 5 : 6 : [] [5,6] = = = = = -> [a] [] [] x : take n xs III.6 Funktionale Programmiertechniken - 10 - take 2 (5 : from 6) = take 2 (from 5) from :: Int -> [Int] from x = x : from (x+1) Unendliche Datenobjekte primes :: [Int] primes = dropall (from 2) III.6 Funktionale Programmiertechniken - 11 - dropall :: [Int] -> [Int] dropall (x:xs) = x : dropall (drop_mult x xs) drop_mult :: Int -> [Int] -> [Int] drop_mult x xs = filter (\y -> mod y x /= 0) xs 1. Erstelle Liste aller natürlichen Zahlen ab 2. 2. Markiere die erste unmarkierte Zahl in der Liste. 3. Streiche alle Vielfachen der letzten markierten Zahl. 4. Gehe zurück zu Schritt 2. Sieb des Eratosthenes primes :: [Int] primes = dropall (from 2) III.6 Funktionale Programmiertechniken - 12 - dropall :: [Int] -> [Int] dropall (x:xs) = x : dropall (drop_mult x xs) drop_mult :: Int -> [Int] -> [Int] drop_mult x xs = filter (\y -> mod y x /= 0) xs take 5 primes = [2,3,5,7,11] primes = [2,3,5,7,11,13,17,19,23,29,31,... Sieb des Eratosthenes