300 likes | 437 Views
Polymorf zoeken. zoek :: (aaBool) [ (a, b) ] a b. MayBe b. No. zoek eq [ ] x = ??? zoek eq ((a,b):ts) x | eq a x = b | otherwise = zoek eq ts x. Yes b. Zelftest. zipWith.
E N D
Polymorf zoeken zoek :: (aaBool) [ (a, b) ] a b MayBe b No zoek eq [ ] x = ??? zoek eq ((a,b):ts) x | eq a x = b | otherwise = zoek eq ts x Yes b
Zelftest zipWith • Schrijf de functie (definitie en type) die overeenkomstige elementen van twee lijsten koppelt met een nader tespecificeren operator > zipWith (+) [1, 2, 3] [4, 5, 6, 7] [5, 7, 9]
Lijst-comprehensies • Notatie 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’) ]
Zelf datastructuren ontwerpen Blad :: Boom a Tak :: a Boom a Boom a Boom a het nieuwetype dataBoom a = Blad | Tak a (Boom a) (Boom a) constructorfuncties types van de parameters van de constructorfuncties
Functies op datastructuren length :: [a] Int length [ ] = 0 length (x:xs) = 1 + length xs • Lijst • Boom omvang :: Boom a Int omvang Blad = 0 omvang Tak x li re = 1 + omvang li + omvang re constructorfuncties
Insert in een zoekboom insert :: (aaOrd) a Boom a Boom a insert cmp e Blad = insert cmp e (Tak x li re) = Tak e Blad Blad f ( ) cmp e x Tak x (insert cmp e li) re Tak x li (insert cmp e re) where f LT = f _ =
3 4 3 4 6 5 1 2 2 4 Toepassing: Breuken typeBreuk = (Int, Int) maal :: Breuk Breuk Breuk plus :: Breuk Breuk Breuk eq :: Breuk Breuk Bool eenvoud :: Breuk Breuk
3 4 6 5 18 20 Breuken vermenigvuldigen • Teller en noemervermenigvuldigen * = maal :: Breuk Breuk Breuk maal (x,y) (p,q) = (x*p, y*q)
+ 1 4 10 40 3 10 22 40 12 40 Breuken optellen • Eerst gelijknamig maken + = = plus :: Breuk Breuk Breuk plus (x,y) (p,q) = (x*q+y*p, y*q)
2 8 3 12 Breuken vergelijken • Kruiselings vermenigvuldigen = = True eq :: Breuk Breuk Bool maal (x,y) (p,q) = x*q == y*p
Toepassing: Polynomen 3.5x4 + 6.1x2 + 2.5 typeTerm = (Float, Int) type Poly = [Term] maal :: Poly Poly Poly plus :: Poly Poly Poly eq :: Poly Poly Bool eenvoud :: Poly Poly
Polynomen optellen • Samenvoegen envereenvoudigen 3x4 + 4x2 2x2 + 1 = 3x4 + 4x2 + 2x2 + 1 + 3x4 + 6x2 + 1 plus :: Poly Poly Poly plus p q = eenvoud (p ++ q)
Polynomen vereenvoudigen • Sorteren op exponenttermen met gelijke exponent samenvoegen 3x4 + 4x2 +2x3 + x2+ 1 = 3x4 + 5x2 + 2x3 + 1 eenvoud :: Poly Poly eenvoud = sorteren verw0 . samenvoegen .
Polynomen vereenvoudigen eenvoud :: Poly Poly eenvoud = verw0 . samen . sorteren sorteren = isort ord where ord :: Term Term Ordering ord (c1,e1) (c2,e2) = ordInt e1 e2 samen ((c1,e1):(c2,e2):ts) | e1==e2 = samen ((c1+c2,e1):ts) | True = (c1,e1) : samen ((c2,e2):ts) samenv ts = ts verw0 = filter ( \(c,e) c/=.0.0 )
Polynomen vermenigvuldigen • Alle termen met elkaar vermenigvuldigen 3x + 1 2x2 + 5 = 6x3+15x + 2x2+5 * maal :: Poly Poly Poly maal p q = eenvoud (cross tMaal p q) tMaal :: Term Term Term tMaal (c1,e1) (c2,e2) = (c1*.c2, e1+e2)
Kruisproduct • Met lijstcomprehensie • Met expliciete recursie cross :: (aab) [a] [a] [b] cross f xs ys = [ f x y | x xs, yys ] cross f [ ] ys = cross f (x:xs) ys = [ ] map (f x) ys ++ cross f xs ys
Ontwerp van functiesop lijsten • Combineer standaardfuncties • Herken je een , , of zoiets?Schrijf dan eerst de hulpfunctie • Gebruik expliciete recursie map filter foldr f [ ] = ... f (x:xs) = ... f xs ...
Voorbeeld 1 afkappen, of aanvullen met spaties • Een string afpassen op een gegeven lengte precies :: Int String String precies n s | n < len = | n == len = | n > len = where len = length s take n s s s ++ replicate (n-len) ’_’
Voorbeeld 2 • Een heleboel strings afpassen op lengte > evenlang 4 [ ”aap”, ”noot”, ”weide” ] [ ”aap_”, ”noot”, ”weid” ] evenlang :: Int [String] [String] evenlang n xs = map f xs where f x = precies n x evenlang n xs = map (precies n) xs
Voorbeeld 3 • Strings even lang maken zonder afkappen > uniform [ ”aap”, ”noot”, ”weide” ] [ ”aap__”, ”noot_”, ”weide” ] uniform :: [String] [String] uniform xs = evenlang n xs where n = maximum (map length xs)
Voorbeeld 4 • Kolommen afpassen in blok van strings > unikol [ [ ”aap”, ”noot”, ”mies” ] , [ ”wim”, ”zus”, ”jet” ] , [ ”weide”,”hok”, ”schapen”] ] [ [ ”aap__”, ”noot”, ”mies___” ] , [ ”wim__”, ”zus_”, ”jet____” ] , [ ”weide”, ”hok_”, ”schapen” ] ]
Kolommen uniformeren aap noot mies wim zus jet weide hok schapen unikol xss = map uniform xss
Kolommen uniformeren aap noot mies wim zus jet weide hok schapen unikol xss = map uniform xss
Kolommen uniformeren aap noot mies wim zus jet weide hok schapen unikol =
Kolommen uniformeren aap noot mies wim zus jet weide hok schapen unikol = wissel
Kolommen uniformeren aap noot mies wim zus jet weide hok schapen unikol = map uniform . wissel
Kolommen uniformeren aap noot mies wim zus jet weide hok schapen unikol = wissel . map uniform . wissel
[4, 6, 8] [3, 5, 7] [2, 4, 6, 8] [1, 3, 5, 7] Wissel wissel ( xs : xss ) [1, 2] [3, 4] [5, 6] [7, 8] = (wissel xss) zipWith (:) xs [1, 2]
Wissel wissel (xs : xss) = zipWith (:) xs (wissel xss) wissel [ ] = repeat [ ] 3 rijen van elk 5 elementen 5 rijen van elk 3 elementen2 rijen van elk 5 elementen 5 rijen van elk 2 elementen1 rij van elk 5 elementen 5 rijen van elk 1 element 0 rijen van elk 5 elementen 5 rijen van elk 0 elementen veel veel oneindig wissel = foldr ... ...
[ ] [2] [2,3] [2,3,4] [ ] [1] [1,2] [1,2,3] [1,2,3,4] Aanloop :: [a] [[a]] aanloop ( x : xs ) 1 2 3 4 = (aanloop xs) [ ] : map ((:) ) x 1