Functioneel programmeren Een snelle herhaling…
Functie-definitie static int kwad (int x) { return x*x ; } kwad x = x * x Haskell kwad :: Int Int
Functie-definitie static int fac (int n) { int tel, res; res = 1; for (tel=1; tel<=n; tel++) res *= tel; return res; } fac n = product [1..n] Haskell fac :: Int Int
Functies als parameter nPas functie toe op alle elementen van een lijst map > map fac [1, 2, 3, 4, 5] [1, 2, 6, 24, 120] > map sqrt [1.0, 2.0, 3.0, 4.0] [1.0, , , 2.0] > map even [1.. 6] [False, True, False, True, False, True]
Herhalen fac :: Int Int fac n = 1 = | n==0 | n>0 “recursie” n * fac (n-1) graag zonder product te gebruiken
Partieel parametriseren nStel: nEn dan: plus :: Int Int Int plus x y = x + y drieMeer :: Int Int drieMeer = plus 3 > map drieMeer [1, 2, 3, 4, 5] [4, 5, 6, 7, 8]
Definitie van map nGeef een recursieve definitie: map :: (a b) [a] [b] map f [ ]= map f (x:xs)= [ ] map f xsf x :
Een ander soort lijst-functies product :: [Int] Int product [ ]= product (x:xs)= 1 product xs x * and :: [Bool] Bool and [ ]= and (x:xs)= True and xs x && sum :: [Int] Int sum [ ]= sum (x:xs)= 0 sum xs x +
Universele “lijst-totalisator” foldr :: [a] a foldr (#) e [ ] = foldr (#) e (x:xs)= e foldr (#) e xs x # (a a a) a zo combineren neutrale waarde
Universele “lijst-totalisator” foldr :: [a] b foldr (#) e [ ] = foldr (#) e (x:xs)= e foldr (#) e xs x # (a b b) b zo combineren neutrale waarde
Had dat eerder gezegd... nAls foldr de generalisatie is van sum, product, en and.... n.... dan zijn sum, product, en and speciale gevallen van foldr product= foldr (*) 1 and= foldr (&&) True sum= foldr (+) 0 or= foldr (||) False
Hoger-ordefuncties op lijsten nDoorloop een lijst en... map :: (a b) [a] [b] filter :: (a Bool) [a] [a] foldr :: (a b b) b [a] b [a] doe dit pak deze combineer zo
Anonieme functies > map f [1.. 4] where f x = x*x + 3*x + 2 [6, 12, 20, 30] > map f [1.. 4] [6, 12, 20, 30] ( \ x x*x+3*x+2 )
Lambda-expressies x*x + 3*x + 2 expressie waar x vrij in voorkomt \ x de functie die die expressie uitrekent
Functies op lijsten > [4, 6, 1] ++ [2, 4] [4, 6, 1, 2, 4] (++) :: [a] [a] [a] [ ] ++ ys= ys (x:xs) ++ ys= x : (xs++ys)
Functies op lijsten > concat [ [3, 4, 5], [ ], [1, 2], [6] ] [3, 4, 5, 1, 2, 6] concat :: [[a]] [a] concat [ ]= [ ] concat (xs:xss)= xs ++ concat xss concat xss= foldr (++) [ ] xss
Oneindige lijsten repeat :: a [a] repeat x= x : repeat x > repeat 3 [3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 replicate :: Int a [a] replicate n x= take n (repeat x) > concat (replicate 5 ”info ” ) ”info info info info info ”
Lazy evaluation nParameters worden pas uitgerekend als ze echt nodig zijn nGeldt ook voor (:) dus alleen deel van een lijst dat echt nodig is wordt uitgerekend
Oneindige lijsten iterate :: (a a) a [a] iterate f x = x : iterate f (f x) > iterate ((+)1) 3 [3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20
Lijst-comprehensies nNotatie uit de verzamelingenleer { x*x | x N, x<10 } > [ x*x | x [1..10], even x ] [4, 16, 36, 64, 100] > [ (x,y) | x [1,4,8], y ”ab” ] [ (1,’a’), (1,’b’), (4,’a’), (4,’b’), (8,’a’), (8,’b’) ]
Lijst-comprehensies nSpeciale notatie nbetekent hetzelfde als maar leest lekkerder dan [ expressie | x lijst, predicaat ] map (\x expressie ) (filter (\x predicaat) lijst )
Zelf datastructuren ontwerpen data Boom a = Blad | Tak a (Boom a) (Boom a) constructor functies het nieuwe type types van de parameters van de constructorfuncties
Opnieuw de lijst uitvinden data Lijst a = Nil | Cons a (Lijst a) constructor functies het nieuwe type types van de parameters van de constructorfuncties
Een datastructuur opschrijven nLijst nBoom [ ] 4 :3 :2 :1 : BladTak 2Blad Tak 4 Blad Blad Tak 7 ( ) ( ) Tak 5 (Tak 1 Blad Blad ) (Blad ) Tak 3 ( ) ( )
Functies op datastructuren nomvang ndiepte omvang :: Boom a Int omvang Blad = 0 omvang (Tak x li re) = 1 + omvang li + omvang re diepte :: Boom a Int diepte Blad = 0 diepte (Tak x li re) = 1 + max (diepte li) (diepte re)