Hogere-ordefuncties nVoeg de elementen van een lijst samen nCombineer twee functies foldr :: (a b b) b [a] b [a] (.) :: (b c) (a b) a c (a c) combineer zo begin hiermee “na”
Lambda-expressies x*x + 3*x + 2 expressie waar x vrij in voorkomt \ x de functie die die expressie uitrekent > map f [1.. 4] [6, 12, 20, 30] ( \ x x*x+3*x+2 )
Zelftest nStel je schrijft een functie f die werkt op lijsten. Wat kun je routinematig alvast opschrijven? uals je recursie gebruikt, en gevalsonderscheid doet met patronen uals je recursie gebruikt, en gevalsonderscheid doet met guards uals je een hogere-ordefunctie (welke?) partieel parametriseert f
f ::.... [a] .... evt. extra parameters Functies op lijsten nBedenk eerst het type! resultaat nRecursie met patronen f [ ]=.... f (x:xs)=....x....f xs.... nRecursie met guards f xs| null xs =.... | True =....f (tail xs).. nZonder recursie f xs = foldr op e xs filter p map g
Functies op lijsten (++) :: [a] [a] [a] concat:: [[a]] [a] head, last:: [a] a tail, init:: [a] [a] take, drop:: Int [a] [a] takeWhile:: (a Bool) [a] [a] eqList:: (a a Bool) [a] [a] Bool
Lijsten polymorf vergelijken nExtra functie meegeven eqList :: (a a Bool) [a] [a] Bool eqList eq [ ][ ] = eqList eq [ ](y:ys) = eqList eq (x:xs)[ ] = eqList eq (x:xs)(y:ys) = True False eq x y && eqList eq xs ys
Lijsten vergelijken > eqList (==) [1,2,3] [1,2,3] True > eqList eqBool [True,False] [True] False > eqList (eqList (==)) [[1,2], [3,4]] [[1,2], [4,3]] False
Ordering nOrdering type met 3 elementen ordInt :: Int Int Ordering ordInt x y| x < y= LT | x==y= EQ | x > y= GT
Lexicografische ordening nLijsten kun je ordenen zoals woorden in een woordenboek ordList :: (a a Ord) [a] [a] Ord > ordList ordInt [1, 2, 3] [1, 2, 4] LT > ordList ordInt [1, 3, 2] [1, 2, 4] GT
Lexicografische ordening ordList :: (a a Ord) [a] [a] Ord ordList ord [ ][ ] = ordList ord [ ](y:ys) = ordList ord (x:xs)[ ] = ordList ord (x:xs)(y:ys) = EQ LT GT f (ord x y) wheref LT = f EQ = f GT = f (....) wheref.... LT ordList ord xs ys GT
Invoegen in een geordende lijst insert :: (a a Ord) a [a] [a] insert ord e [ ]= [e] insert ord e (x:xs)= f (ord e x) wheref LT= e : x : xs f _= x : insert ord e xs isort :: (a a Ord) [a] [a] isort ord [ ]= [ ] isort ord (x:xs)= insert ord x (isort ord xs) isort ord = foldr (insert ord) [ ]
Geordende lijsten samenvoegen merge :: (a a Ord) [a] [a] [a] merge ord [ ] ys= ys merge ord xs [ ]= xs merge ord (x:xs) (y:ys)= f (ord x y) wheref LT= x : merge ord xs (y:ys) f _= y : merge ord (x:xs) ys > merge ordInt [1, 3, 4] [2, 5, 6] [1, 2, 3, 4, 5, 6]
Primitieve types nIntgehele getallen nFloatgetallen met decimale punt nBoolTrue False nOrderingLT EQ GT nChar’a’ ’b’ ’A’ ’2’ ’#’
Char: lettertekens nConstanten nVergelijken nConversie ’a’ ’A’ ’1’ ’;’ eqChar :: Char Char Bool ordChar:: Char Char Ordering ord :: Char Int chr:: Int Char
String: lijst charcters nConstanten ”hoi” ”CKI” ”a12#” > map ord ”CKI” [67, 75, 73] eqString :: String String Bool eqString= eqList eqChar > eqString ”CKI” (map toUpper ”cki”) True
Functies op Strings words:: String [String] unwords:: [String] String > words ”dit is een zin” [ ”dit”, ”is”, ”een”, ”zin” ] > unwords [”dit”, ”zijn”, ”losse”, ”woorden”] ”dit zijn losse woorden”
unwords en words unwords[ ]= unwords[w]= unwords(w:ws)= words[ ]= wordscs= where eerste= rest= [ ] w w ++ ” ” ++ unwords ws [ ] eerste : words rest takeWh (not.isSp) cs dropWh (not.isSp) cs dropWh isSp ( )
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 ”CKI ” ) ”CKI CKI CKI CKI CKI ”
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
5678 [5678, 567, 56, 5, 0, 0, [5678, 567, 56, 5] [8, 7, 6, 5] [5, 6, 7, 8] [’5’, ’6’, ’7’, ’8’] int2string = f5.f4.f3.f2.f1 where f1 = f2 = f3 = f4 = f5 = Functies combineren iterate (\x x/10) takeWhile ((/=)0) map (\x x-10*(x/10)) reverse map (\x chr(x+48)) ”5678”
Datastructuren nLijst variabel aantal hetzelfde type nTupel vast aantal verschillend type rij :: [Int] rij = [1, 2, 3, 4, 5] paar:: (Int, String) paar = (3, ”hoi”)
Lijst van tupels telefoonboek :: [ (String, Int) ] telefoonboek = [ (”Jeroen”, 4118), (”Bastiaan”, 2585), (”Jur”, 3283), (”Arjan”, 1012) ] zoek :: [ (String, Int) ] String Int > zoek telefoonboek ”Bastiaan” 2585
Zoek in lijst van tupels zoek :: [ (String, Int) ] String Int zoek [ ] vraag = 0 zoek ( t : ts ) vraag > zoek telefoonboek ”Bastiaan” 2585 | eqString vraag naam = nr | otherwise = zoek ts vraag (naam,nr)
Char en String nCharéén letter uord ::Char Int uchr ::Int Char nString[Char] uwords :: String [String] uunwords :: [String] String ”hoi” ”CKI” ”a12#” ’a’ ’A’ ’1’ ’;’
Oneindige lijsten nOneindige lijst nLazy evaluation: oneindige lijst als tussenresultaat antwoord toch in eindige tijd repeat :: a [a] repeat x= x : repeat x