Hogere-orde functies: herhaald patroon? Parametrizeer! 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-loper: foldr foldr :: [a] a foldr (#) e [ ] = foldr (#) e (x:xs)= e foldr (#) e xs x # (a a a) a combineer-functie foldr :: (a b b) b [a] b start-waarde
Partiële parametrizatie nfoldr is een generalisatie van sum, product, en and.... n…dus sum, product, en and kun je schrijven met foldr product= foldr (*) 1 and= foldr (&&) True sum= foldr (+) 0 or= foldr (||) False
Voorbeeld: sorteren (1/2) insert :: a [a] [a] insert e [ ] = [ e ] insert e (x:xs) | e x= e : x : xs | e x= x : insert e xs Ord a isort :: [a] [a] isort [ ]= [ ] isort (x:xs)= insert x (isort xs) Ord a isort = foldr insert [ ]
Voorbeeld: sorteren (2/2) qsort :: [a] [a] qsort [ ] = [ ] qsort (x:xs)= qsort (filter (<x) xs) ++ [x] ++ qsort (filter ( x) xs) Ord a (Waarom hebben ze me nooit eerder verteld dat ‘t zo makkelijk is?)
Handige notaties (geleend uit de wiskunde) nLambda abstractie nLijst comprehensie \x x*x [ x*y | x [1..10], even x, y [1..x] ] Om naamloze functies te maken intuitiever dan combinatie van map, filter & concat
Deel II Boomstructuren in Haskell
Binaire bomen met interne waarden Hoe codeer je dat in Java/C++/C# enz?
OO-aanpak van bomen class Tree {private Tree left, right; private int value; // constructor public Tree(Tree al, Tree ar, int av) {left = al; right=ar; value=av; } // bladeren gecodeerd met null }
OO-aanpak van bomen: binaire bomen met externe data class Tree { // lege superclass } class Leaf extends Tree { int value } class Node extends Tree { Tree left,right }
Functionele aanpak van bomen nIk wil een polymorf type nEn constructorfuncties Leaf :: a Tree a Node :: Tree a Tree a Tree a Tree a data Tree a = Leaf a | Node (Tree a) (Tree a) nHaskell notatie:
definition = type Name type var typ = type Name data type var context constructor Name type | declaration constructor operator
Functies op bomen nNaar analogie van lijst-functies nschrijf je een functie op een boom: length :: [a] Int length [ ]= 0 length (x:xs)= 1 + length xs size :: Tree a Int size (Leaf v) = 1 size (Node lef rit) = size lef + size rit
Uitdaging: schrijf boom-functies nelem kijkt of een waarde in een boom zit nfront verzamelt alle waarden in een lijst elem :: a Tree a Bool elem x (Leaf y) = x==y elem x (Node lef rit)= elem x lef || elem x rit front :: Tree a [a] front (Leaf y) = [ y ] front (Node lef rit)= front lef ++ front rit Eq a
Toepassing: expressies type Expr= (3*a + 4*b) / c plus:: Expr Expr Expr maal:: Expr Expr Expr waarde :: [(String,Int)] Expr Int eenvoud :: Expr Expr
Expressies: poging 1 type Expr= (3*a + 4*b) / c String plus:: Expr Expr Expr waarde :: [(String,Int)] Expr Int plus a b = a ++ “+” ++ b waarde tab s = foldr ??? ??? s 3+a4+b *
Expressies: poging 2 data Expr = | constructorfuncties waarmee je een Expr bouwt Con Var Plus Min Maal Deel Int String Expr types van de parameters die daarbij nodig zijn
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 ( ) ( )
Een datastructuur opschrijven nExpr (Maal (Con 3) (Var “a”)) (Maal (Con 4) (Var “b”)) (3*a + 4*b) / c Plus Deel ( ) ( Var “c” )
Expressies: poging 3 data Expr = | constructorfuncties waarmee je een Expr bouwt Int String Expr Con Var :+: :-: :*: :/: Constructoren beginnen met hoofdletter of dubbelepunt constructorfuncties/operatoren waarmee je een Expr bouwt
Een datastructuur opschrijven nExpr Con 3 :*: Var “a” Con 4 :*: Var “b” (3*a + 4*b) / c :+: ( ) :/: ( Var “c” ) infixl 6 (:+:), (:-:) infixl 7 (:*:), (:/:)
Functies op Expressies plus:: Expr Expr Expr maal:: Expr Expr Expr waarde :: [(String,Int)] Expr Int eenvoud :: Expr Expr plus = (:+:) maal = (:+:)
Functies op Expressies wrd :: [(String,Int)] Expr Int wrd t (Con n) wrd t (Var v) wrd t (a:+:b) wrd t (a:-:b) wrd t (a:*:b) wrd t (a:/:b) ============ n zoekop t v wrd t a + wrd t b wrd t a – wrd t b wrd t a * wrd t b wrd t a / wrd t b
Functies op Expressies afg :: Expr String Expr afg (Con c) dx afg (Var v) dx = Con 0 | eqString v dx = Con 1 | otherwise = Con 0 afg (a:+:b) dx afg (a :-:b) dx = afg a dx :+: afg b dx = afg a dx :-: afg b dx “de afgeleide naar een variabele”
Functies op Expressies afg :: Expr String Expr afg (a:*:b) dx afg (a :/:b) dx = a :*: afg b dx :+: b :*: afg a dx = ( b :*: afg a dx :-: a :*: afg b dx ) :/: (b :*: b)
Twee soorten berekening nNumeriek nSymbolisch diff :: (Float Float) (Float Float) diff f x = (f (x+h) – f x) / h where h = afg :: Expr String Expr afg (Con c) dx = Con 0 afg (Var v) dx | eqString v dx = Con 1 |otherwise = Con 0 afg (a:+:b) dx = afg a dx :+: afg b dx afg (a:*:b) dx = a :*: afg b dx :+: b :*: afg a dx dat is nou AI!
Rekenen met Booleans (&&) :: Bool Bool Bool (||) :: Bool Bool Bool not :: Bool Bool True && y= y False && y= False True || y= True False || y= y notTrue= False notFalse= True
Symbolisch Proposities bewerken data Prop = | constructorfuncties waarmee je een Expr bouwt Bool String Prop Con Var Not :/\ :\/ :-> constructorfuncties/operatoren waarmee je een Prop bouwt
Functies op Proposities type Bedeling = [(String,Bool)] evalueer :: Bedeling Prop Bool > evalueer [ (“p”,True), (“q”, False) ] (Var “p” :/\ Var “q”) False
Functies op Proposities tautologie :: Prop Bool contradictie :: Prop Bool > tautologie (Var “p” :\/ Not (Var “p”)) True > contradictie (Var “p” :-> Var “q” ) False
Functies op Proposities equivalentie :: Prop Prop Bool vervulbaar :: Prop [Bedeling] > vervulbaar (Var “p” :-> Var “q” ) [ [ (“p”,True),(“q”,True) ], [ (“p”,False),(“q”, False) ], [ (“p”,False),(“q”, True) ] ]
Functies op Proposities eenvoudig :: Prop Prop > eenvoudig Not(Not (Var “p” :/\ (Var “q” :\/ Not Var “q”)) Not (Not (Var “p” :/\ Con True)) Not (Not (Var “p”)) Var “p” tautologieën en contradicties vervangen door constanten operatoren met constante parameters wegwerken dubbele Not wegwerken
Functies op Proposities normaalvorm :: Prop Prop > normaalvorm (Not (Not Var “p” :\/ Var “q” ) Var “p” :/\ Not Var “q” Not alleen voor variabelen
Functies op Proposities toon :: Prop String ontleed:: String Prop > putStr (toon (Var “p” :-> Var “q”)) p -> q > ontleed “p && !p” Var “p” :/\ Not Var “p”
Functies op Proposities evalueer:: Bedeling Prop Bool tautologie:: Prop Bool contradictie:: Prop Bool equivalentie:: Prop Prop Bool vervulbaar:: Prop [Bedeling] eenvoudig:: Prop Prop normaalvorm:: Prop Prop toon:: Prop String ontleed:: String Prop