(S)DT 2012-20131 Haskell Functioneel programmeren.

Slides:



Advertisements
Verwante presentaties

Advertisements

KINN 2010 •OOP •O Object •O Georiënteerd •P Programmeren.
Instructie Programmeren Task 1 5JJ70. Task 1.1: Hello World •Klik naast de laatste accolade in de grijze kantlijn om een breakpoint neer te zetten, anders.
Inleiding programmeren in C++ Life Science & Technology 1 maart Universiteit Leiden.
Algoritmen en Datastructuren (ALDAT)
Lijsten in de -calculus Een lijst [E 1, E 2,..., E n ] kan in de -calculus voorgesteld worden als z.((z E 1 ) z.((z E 2 )... z.((z E n ) nil)...) met nil.
Deel I: Functionele Programmeertalen Hoofdstuk 4: Functioneel Programmeren.
Uitwerking tentamen Functioneel Programmeren 29 januari 2009.
Instructie Programmeren Task 8 5JJ70. PAGE 2 Task 8: Double Linked List Het doel van deze opdracht is: Het opbouwen van een tweetal klassen, die samen.
Practica Computerlinguistiek Tekst en uitleg:
Hogere-ordefuncties nEen lijst langs lopen en met elk element iets doen nEen lijst langs lopen en sommige elementen selecteren map filter.
Datastructuren Analyse van Algoritmen en O
Datastructuren Analyse van Algoritmen en O
VBA en VBS Een introductie.
Computervaardigheden Hoofdstuk 4 — Scripting (Let op: dit is enkel voor studenten Biologie.)
Hoofdstuk 6: Controle structuren
 - congruentie -regel:
1 SOCS Hoofdstuk 1 Programmeertaal C. 2 Kenmerken van C Hogere programmeertaal  Grote verzameling types, strenge type controle  Zelf nieuwe types definiëren.
Polymorf zoeken zoek :: (a  a  Bool)  [ (a, b) ]  a  b zoek eq [ ] x = ??? zoek eq ((a,b):ts) x | eq a x = b | otherwise = zoek eq ts x MayBe b No.
1 Datastructuren Sorteren: alleen of niet alleen vergelijkingen College 5.
1 Datastructuren Sorteren: alleen of niet alleen vergelijkingen (II) College 6.
Hogere-orde functies: herhaald patroon? Parametrizeer! product :: [Int]  Int product [ ]= product (x:xs)= 1 product xs x * and :: [Bool]  Bool and [
Functies op Proposities evalueer:: Bedeling  Prop  Bool tautologie:: Prop  Bool contradictie:: Prop  Bool equivalentie:: Prop  Prop  Bool vervulbaar::
Hoger-ordefuncties op lijsten nDoorloop een lijst en... map :: (a  b)  [a]  [b] filter :: (a  Bool)  [a]  [a] foldr :: (a  a  a)  a  [a]  a.
Parallelle Algoritmen String matching. 1 Beter algoritme patroonanalyse Bottleneck in eenvoudig algoritme: WITNESS(j) (j = kandidaat in eerste i-blok)
Assenstelsels en het plotten van Functies in LOGO
Functies als Getallen Jan Martin Jansen.
Numerieke Natuurkunde
-calculus.
Functies definiëren nDoor combinatie van standaardfuncties fac :: Int  Int fac n = product [1..n] oneven :: Int  Bool oneven n = not (even n) negatief.
Char en String nCharéén letter uord ::Char  Int uchr ::Int  Char nString[Char] uwords :: String  [String] uunwords :: [String]  String ”hoi” ”CKI”
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.
Reguliere talen nReguliere grammatica: versimpelde Contextvrije grammatica nFinite-state Automaton: andere manier om een taal te beschrijven nReguliere.
Imperatief programmeren nProgramma bestaat uit nRunnen is opdrachten gegroepeerd in methoden één voor één uitvoeren te beginnen met main.
Functioneel Programmeren Daan Leijen. Wat gaan we doen? 3 fundamentele principes van computatie Equationeel redeneren IO-monad GUI's in Haskell (wxHaskell)
6.1 Inleiding HOOFDSTUK 6 METHODEN
P. 1 Vakgroep Informatietechnologie Structuur Deel II C++ Classes Namespaces Type casting Reference types Constructors en Destructors Memory Management.
Datastructuren Sorteren, zoeken en tijdsanalyse
Sorteeralgoritmen. Sorteren: aanpak 1 Hoe ga je een rij getallen sorteren met PC? Sorteren door selectie (= selection sort): Zoek de kleinste waarde Sorteer.
Chris Pollentier 18 / 12 / 2002 De LOGO taalwereld.
KINN 2010 OOP O Object O Georiënteerd P Programmeren.
PHP & MYSQL LES 02 PHP & FORMULIEREN. PHP & MYSQL 01 PHP BASICS 02 PHP & FORMULIEREN 03 PHP & DATABASES 04 CMS: BEST PRACTICE.
PHP & MYSQL LES 01 PHP BASICS. PHP & MYSQL 01 PHP BASICS 02 PHP & FORMULIEREN 03 PHP & DATABASES 04 CMS: BEST PRACTICE.
Taal nEen Alfabet is… een eindige verzameling symbolen nEen Taal is… een deelverzameling van T* bij een bepaald alfabet T nEen Zin is… een element van.
Inleiding tot programmeren
Variabelen en berekeningen
Tircms03-p les 2 Hfdst 3,4 Meer operatoren Functies.
Tircms02-p les 3 Functies Strings Structuren. Functies 1. main() 2. { int k; k = 10 ; printf(“%d\n”,fac(k)); } 3. int fac(n) int n; 4. { int f; f= 1;
Tircms02-p les 2 Meer operatoren Arrays en pointers Types en conversie.
tircms02-p les 1 Operating Systems practicum
1 Introductie next MCT - Programmeren 2 © S. Walcarius Waarom java? programma machinetaal (.exe) compilen platformspecifiek Een exe programma.
PROGRAMMEREN LOGISCH en FUNCTIONEEL Ik zeg wat ik denk!
Functioneel programmeren Een snelle herhaling…. Functie-definitie static int kwad (int x) { return x*x ; } kwad x = x * x Haskell kwad :: Int  Int.
AWK A Pattern scanning and processing language made by Aho Weinberger Kernighan and explained by Albert Montijn.
(S)DT Haskell Deel 2 list comprehensions, types en type klassen, programma transformatie, I/O.
1 PI1 week 9 Complexiteit Sorteren Zoeken. 2 Complexiteit van algoritmen Hoeveel werk kost het uitvoeren van een algoritme (efficiëntie)? –tel het aantal.
Hoorcollege 1: efficiëntie en complexiteitsontwikkeling.
Hoorcollege 1: efficiëntie en complexiteitsontwikkeling.
Les 3 - Operators Workshop Php Basic. ICT Academy Php Basic Content Operators Wiskundig Toewijzing Vergelijking.
IF() ELSE() LES 4: VOORWAARDEN. BOOL Een variabele die slechts 2 mogelijke waarden kan hebben: true(waar) of false(niet waar) duid je aan met bool bool.
Informatie beoordelen If else Switch En Wiskunde.
Berekening van de Orde Van een Algoritme
Programmeren met Reeksen
Gameprogrammeren: Expressies
Tinpro015b-les 1 C++ voor C-kenners Voor Technische Informatica.
Gameprogrammeren: Herhalingen
Tinpro015b-les3 Hfdst 3,4 Meer operatoren Functies.
-calculus versus Scheme
Gameprogrammeren: Arrays
Python – For loop + strings
Transcript van de presentatie:

(S)DT Haskell Functioneel programmeren

Bijkomend materiaal de Haskell website Op de "Learning Haskell" pagina vind je veel bijkomende informatie. Je vindt er online materiaal, bijvoorbeeld Learn You a Haskell for Great Good (tutorial) Yet Another Haskell Tutorial of een nederlandstalige cursustekst ( (S)DT

Bijkomend materiaal In de didactische cluster van de CBA vind je Programming in Haskell Graham Hutton, University of Nottingham Cambridge University Press, January 2007 ( Ook video lectures gebaseerd op het boek!! !!!!! Er is een online manual die je ook tijdens het examen lokaal kan raadplegen: not ( (S)DT

Bijkomend materiaal !!!!! Er is een online manual die je ook tijdens het examen lokaal kan raadplegen: not ( Maar, (Gequoteerde) oefeningen + modeloplossingen (S)DT

5 Haskell Deel 1 Introductie; lijsten in Haskell; lui uitvoeringsmechanisme; polymorfe functies

(S)DT Een eenvoudig Haskell programma fib :: Int -> Int -- een typedeclaratie voor fib fib 0 = 1 fib 1 = 1 fib n = (fib (n-1)) + (fib (n-2)) fib is een recursieve functie die kan toegepast worden op 1 argument dat een integer moet zijn en dan als waarde een integer teruggeeft. zet definitie in een bestand, bijvoorbeeld f.hs laad in in ghci (Haskell platform doe functie-oproepen

(S)DT # GHCi, version : :? for help commentaar tot einde lijn Prelude> :load f -- :load is directief Main> fib 3 -- pas fib toe op resultaat is 3 Main> fib 6 13 Main> fib (-1) ……………………………… computatie gebeurt door.... Functionele taal …. Bouwstenen in je programma’s: herbruikbare functies (die modelleren algoritmen) Expressies in een functionele taal : waarde gebaseerd

(S)DT Main> :type fib fib :: Int -> Int Main> :type (+) (+) :: Num a => a -> a -> a “Voor alle types a die de Num operaties ondersteunen”, (+) is een functie die twee argumenten van het type a afbeeldt op een resultaat van het type a. Int is een voorbeeld van een type dat de Num operaties ondersteunt: de funties (+), (-), (*),...

(S)DT variabele a Main> fib a :1:4: Not in scope: `a‘ Main> fib "asd“ -- de string "asd“ is in feite een lijst van Char -- [Char] -- type fout: [Char] is geen Int :1:0: Couldn't match expected type `Int' against inferred type `[Char]' In the first argument of `fib', namely `"asd"' In the expression: fib "asd" In the definition of `it': it = fib "asd"

(S)DT Haskell: merk op Haskell is getypeerd (statisch en sterk) een functie wordt gedefinieerd aan de hand van verschillende clauses (pattern) matching gebeurt van boven naar onder en eerste argumenten-match wordt genomen er zijn “ingebouwde” functies (+ - ) veranderlijken en functienamen beginnen met kleine letter type begint met een hoofdletter (enkel al Int) functies met letter in prefix (kan anders) speciale tekens in infix

(S)DT Syntactisch alternatieve definitie van fib fib n = if n == 0 then 1 -- else verplicht else if n == 1 then 1 else (fib (n-1)) + (fib (n-2)) Maar fib n = if n == 0 then 1 else if n == 1 then 1 else (fib (n-1)) + (fib (n-2)) Prelude>:l f.hs [1 of 1] Compiling Main ( fib.hs, interpreted ) f.hs:14:0: parse error (possibly incorrect indentation) Failed, modules loaded: none.

(S)DT Andere versies van fib fib :: Int -> Int fib2 :: Int -> Int -> Int -> Int fib n = fib2 n 1 0 fib2 0 n _ = n fib2 i n m = fib2 (i-1) (m+n) n vroeger Main> fib nu Main> fib

Interactieve evaluatie (:set +t) Main> it :: Integer Main> it it :: Integer Main> let x = 3+4 x :: Integer Main> x 7 it :: Integer Main> :show bindings x :: Integer = 7 it :: Integer = 7 (S)DT

(S)DT Haskell: merk verder op waar zijn de typedeclaraties bij sommige vb? het type van een functie die meerdere argumenten kan hebben wordt genoteerd door A1 -> A2 -> A3 -> R

(S)DT Type-declaraties, -inferentie en -checking f a b = g a (h b) -- haakjes zijn nodig g :: R -> S -> T … -- definitie van g h :: Q -> P … -- definitie van h 1. het type van f moet dan zijn: f :: R -> Q -> T 2. is het type van g en h consistent? enkel indien P == S -- beetje te straf Haskell kan types infereren (1) en nakijken (2) gebaseerd op Hindley-Milner type systeem (van ML)

(S)DT Currying en waarom de haakjes? eigenlijk heeft een functie altijd maar 1 argument en is dus een “curried” functie voor een functie f :: A -> B -> C hebben we dat (f a) :: B -> C dus, een functie met n argumenten, toegepast op 1 argument geeft als resultaat een functie met n-1 argumenten bovenstaande declaratie is equivalent met f :: A -> (B -> C) en totaal verschillend van f :: (A -> B) -> C tenslotte, g a h b == (((g a) h) b) en niet g a (h b)

(S)DT Curried versie van de optelling -- versie met tuple als argument add :: (Int,Int) -> Int add (x,y) = x + y -- curried versie cadd cadd :: Int -> Int -> Int cadd x y = x + y -- hetzelfde resultaat maar voor cadd wordt er eerst (cadd x) berekend en dan … -- -> is rechts-associatief dus geen haakjes nodig in cadd :: Int -> (Int -> Int) -- functie-oproepen zijn links-associatief dus geen haakjes nodig in cadd 3 4 want is in feite ((cadd 3) 4) --

Curried functies Meer flexibel dan functies met tuples Partieel toegepaste functies kunnen erg nuttig zijn plus4 = (cadd 4) -- enkele nuttige functies gedefinieerd door sections isNul = (== 0) verdubbel = (2*) tweeTotde = (2^) Een infix operator is in feite ook een curried functie (+) 1 2 (S)DT

(S)DT Operator section partieel toegepaste operator: (+ 3) en (3 +) (op a) b = b op a (a op) b = a op b Main>:t (-3) (-3) :: (Num a) => a

(S)DT Currying, genoemd naar Haskell Curry Logicus die rond functie theorie werkte een simpel theoretisch model: enkel functies met 1 argument, bv. lambda calculus f :: (Int -> Int) -> Int -> Int f g a = g a -- apply g to a Main> f (+3) 4 7 Main> f (3-) 4 Main> f (*4) 4 16 Wat is (f (3+))? Alternatieve def voor f? (3+) $ 4

(S)DT Verschil f :: ( Int -> Int -> Int) -> Int -> Int -> Int f g a b = g a b Main> f (+) Main> f (-) 3 4 Wat is (f (+))? Wat is f?

(S)DT Hogere orde functies functies kunnen als argument een functie hebben functies kunnen als resultaat een functie teruggeven functies kunnen als parameter van andere functies worden gebruikt -- later toepassen van een functie f op 1 argument a noteren we door (f a) eventueel zonder haakjes vergelijk met Lisp (f a b)!!!

(S)DT Geschiedenis : functies als berekeningsmodel, M. Schönfinkel, Haskell Curry en Alonzo Church (lambda calculus) 1950: eerste functionele programmeertaal, Lisp van John McCarthy (emacs) 1978: Backus (Fortran;Backus Naur Form) in zijn Turing Award Lecture: “Can programming be liberated from the Von Neumann style” pleidooi voor echt functioneel programmeren 1980: getypeerde functionele talen programmeertalen: ML, Scheme (een aanpassing van Lisp), Miranda, Gofer, Clean

(S)DT Geschiedenis 1987: groep onderzoekers definieren de taal Haskell Richard Bird, Paul Hudak, John Hughes, Neil Jones, Simon Peyton Jones, Philip Wadler,.... “referential” transparantie “substitute equals for equals”

(S)DT

Prelude The Prelude: a standard module imported by default into all Haskell modules. For more documentation, see the Haskell 98 Report GHC Documentation (Basic) Libraries Prelude, Data.List specificaties + source (S)DT

(S)DT !!!! Haskell.html (en ook oude versie) The Haskell reference is based on Haskell 98 Report and Haskell 98 Libraries Report and a substantial part of descriptions comes from these specifications.

(S)DT Let expressies fib n = if n == 0 then 0 else if n == 1 then 1 else let a = fib (n-1) b = fib (n-2) in a + b a en b zijn lokale variabelen binnen de laatste else tak de = is geen toekenning!!! Maar … let y = a*b f x = (x+y)/y in f c + f d

(S)DT Where clauses fib :: Int -> Int fib n = fib2 n 1 0 where fib2 0 n _ = n fib2 i n m = fib2 (i-1) (m+n) n fib2 is lokaal aan fib (clause die er juist voor staat) fib2 is elders niet zichtbaar fib2 heeft geen type declaratie genest gebruik van syntax mogelijk

(S)DT To do start ergens ghci op type wat kleine programma’s in laad en voer de oproepen uit maak fouten tegen types, indentatie en syntax definieer max :: Int -> Int -> Int max a b en ook maxdrie a b c schrijf minstens 1 nieuwe hogere orde functie ontdek een probleem met fib (2^100)

LIJSTEN IN HASKELL (S)DT

(S)DT Lijsten in Haskell een lijst is een rij zonder constante tijd random toegang en gegeven een lijst kan er in constante tijd een element aan toegevoegd worden (van voor). (anders is het een array) een lijst is leeg of een element gevolgd door een lijst een lijst heeft elementen die alle hetzelfde type hebben.

(S)DT Een lijst van Int een lege lijst [] lijst met elementen [4,5,1] alternatieve notaties voor [4,5,1] 4 : [5,1] 4 : 5 : 1 : [] Prelude> :t (:) (:) :: a -> [a] -> [a] Hoe in Prolog??

(S)DT Lijsten aan elkaar hangen append :: [Int] -> [Int] -> [Int] append [] l = l append (x:xs) a = x : (append xs a) Is er een verschil met het concateren van lijsten in Prolog of linked lists in Java? In Prelude [] ++ ys = ys (x:xs) ++ ys = x : (xs ++ ys) Let op: append x:xs wordt opgevat als (append x) : xs

Herschrijven als uitvoeringsmodel [] ++ ys = ys (x:xs) ++ ys = x : (xs ++ ys) [1,2] ++ [4,5] = (1:2:[]) ++ (4:5:[]) = 1 : ((2:[]) ++ (4:5:[])) = 1 : 2 : ([] ++ (4:5:[])) = 1 : 2 : 4 : 5 : [] (S)DT

(S)DT Let op: vergelijk [2] ++ [3,4,5] 2 ++ [3,4,5] :1:0: No instance for (Num [a]) arising from the literal `2' at :1:0 Possible fix:add an instance declaration for (Num [a]) In the first argument of `(++)', namely `2' In the expression: 2 ++ [3, 4, 6] In the definition of `it': it = 2 ++ [3, 4, 6]

(S)DT Let op: vergelijk 2 : [3,4,5] [2] : [3,4,5] No instance for (Num [t]) arising from the literal `5' at :1:11 Possible fix:add an instance declaration for (Num [t]) In the expression: 5 In the second argument of `(:)', namely `[3, 4, 5]' In the expression: [2] : [3, 4, 5]

(S)DT Lengte van een lijst listlength :: [Int] -> Int listlength [] = 0 listlength (x:xs) = 1 + (listlength xs) of listlength l = ll l 0 where ll [] acc = acc ll (x:xs) acc = ll xs (acc+1) Is er een reden om de ene beter te vinden dan de andere?

(S)DT Insertion sort isort :: [Int] -> [Int] isort [] = [] isort (x:xs) = insert x (isort xs) where insert x [] = [x] insert x (y:ys) = if x < y then (x: y : ys) else (y: (insert x ys))

(S)DT To do schrijf een functie die van een lijst van Ints enkel de positieve getallen behoudt schrijf een functie die de som teruggeeft van de positieve getallen in een lijst van Ints. schrijf een functie die het maximum van een lijst van Ints teruggeeft

LUI UITVOERINGSMECHANSIME (S)DT

(S)DT Parameter passing mechanisme Wat ken je al?  Java: call by value actueel argument wordt geëvalueerd voor de methode wordt opgeroepen  ?? Haskell: actueel argument wordt geëvalueerd wanneer de waarde ervan nodig is Haskell is lui Haskell heeft call by need

(S)DT Wat betekent lui? g a b = h (a+b) h i = 9 > g 3 4 Waarom ooit de (3+4) uitrekenen als geen enkele functie die waarde ooit zal gebruiken?

(S)DT De essentie van luiheid Een expressie wordt maar gereduceerd tot een waarde indien de waarde nodig is. Een expressie wordt slechts één keer gereduceerd tot een waarde kwadraat i = i * i telop x y = x + y kwadraat (telop 6 2) contrasteer met call by value, call by name

(S)DT Voorbeeld && : luie evaluatie van argumenten (&&), (||) :: Bool -> Bool -> Bool False && x = False True && x = x False || x = x True || x = True Prelude> 4 < 5 && 3 < (5/0) Program error???? Ghci: True -- 3 < Infinitity !! Prelude> 5 < 4 && 3 < (5/0) False

(S)DT Voorbeeld: luie matching f :: [Int] -> [Int] -> Int f [] y = 0 add1 [] = [] f (a:x) [] = 0 add1 (x:xs) = (x+1): add1 xs f (a:x) (b:y) = a + b f (add1 [4,5,6]) (add1 [10,20,30]) = f ((4+1):add1 [5,6]) (add1 [10,20,30]) = f (5:add1 [5,6]) (add1 [10,20,30]) = f (5:add1 [5,6]) (11: add1 [20,30]) = = 16

Wat met accumulator versie van listlength?? listlength l = ll l 0 where ll [] acc = acc ll (x:xs) acc = ll xs (acc+1) Wat gebeurt er met (acc+1)??? De hele som wordt opgebouwd voor ze wordt berekend!! where llstrict [] l = l llstrict (x:xs) l = llstrict xs $! (l+1) -- f $! x behaves as f x, except that the evaluation of the argument x is forced before f is applied (S)DT

(S)DT Luiheid en oneindige lijsten plus1 :: [Int] -> [Int] plus1 [] = [] plus1 (x: xs) = (x+1) : (plus1 xs) langelijst :: [Int] langelijst = (1 : (plus1 langelijst)) -- (*) langelijst is een functie zonder argumenten, enkel resultaat langelijst is een waarde die voldoet aan de vergelijking (*) met call by value is (*) een onmogelijke definitie zolang we maar eindig veel delen van langelijst nodig hebben is er geen probleem: Haskell zal er niet meer berekenen

(S)DT Hoe eindig veel elementen van een oneindige lijst gebruiken? take :: Int -> [Int] -> [Int] take 0 _ = [] take n (x:xs) = x : take (n-1) xs fib :: [Int] fib = (1:1: (f 1 1 )) where f a b = (a+b): (f b (a+b)) Main> take 3 [1,2,3,4,5] [1,2,3] Main> take 10 fib [1,1,2,3,5,8,13,21,34,55] Wat is de waarde van fib ? Welke functie zorgt voor welke evaluatie?

(S)DT Kijk zelf na Main> take 3 langelijst [1,2,3] Welke functie zorgt voor de evaluatie van welke uitdrukking???

isSorted :: [Int] -> Bool isSorted [] = True isSorted [_] = True isSorted (x:y:ys) = (x <= y) && isSorted (y:ys) iterate :: (a -> a) -> a -> [a] iterate next x = x : iterate next (next x) Main> isSorted (iterate (`div` 2) 8) Main> isSorted (iterate (`div` 2) (-100)) Main> iterate (`div` 2) (factorial 100) (S)DT Extra voorbeeld

POLYMORFE FUNCTIES (S)DT

(S)DT Een voorbeeld listlength:: [Int] -> Int listlength [] = 0 listlength (_:xs) = 1 + listlength xs Wat is er aan de clauses van listlength dat maakt dat het alleen zou werken voor [Int] ? Kan het ook werken met elementen van een ander type? een willekeurig type? Niet met die typedeclaratie natuurlijk!!

(S)DT Nu als polymorfe functie listlength:: [t] -> Int listlength [] = 0 listlength (_:xs) = 1 + listlength xs t is een type-veranderlijke !! lees bv. als: voor elk type t is listlength een functie die toegepast op een lijst met type t elementen een Int berekent belangrijk: alle elementen van de lijst moeten van hetzelfde type zijn!!!

(S)DT Bekende functies: polymorfe versie append :: [t] -> [t] -> [t] append [] l = l append (x:xs) a = x : append xs a -- waarom niet [a] -> [b] -> [c] ??? take :: Int -> [t] -> [t] take 0 _ = [] take n (x:xs) = x : take (n-1) xs

(S)DT Nieuwe polymorfe functies id :: a -> a -- identiteits-functie id x = x map :: (a -> b) -> [a] -> [b] map f [] = [] map f (h: r) = (f h) : map f r Main> map (+1) [1,2,3] [2,3,4] g i = if i > 0 then True else False > map g [-1,3,-4,4] meer dan 1 type parameter!!! soms a == b

(S)DT Tuples lijsten versmelten en een nieuw data type zip :: [a] -> [b] -> [(a,b)] zip []_ = [] zip _ [] = [] zip (x:xs) (y:ys) = ( (x,y) : (zip xs ys)) Main> zip [1,2,3,4] [True,False,True] [ (1,True), (2,False), (3,True)] tuples van elke grootte zijn ingebouwd en pattern matchen enkel met tuples van gelijke grootte

(S)DT Guards als syntactische suiker merge :: [Int] -> [Int] -> [Int] merge [] l = l merge l [] = l merge (x:xs) (y:ys) = if (x < y) then (x : merge xs (y:ys)) else if x > y then (y : merge (x:xs) ys) else (x : merge xs ys) -- of ook : laatste clause met guards merge (x:xs) (y:ys) | x < y = (x : merge xs (y:ys)) | x > y = (y : merge (x:xs) ys) | True = (x : merge xs ys)

(S)DT Verschillende stijlen in Haskell: declaratie expressie een functie-definitie is een opeenvolging van onafhankelijke gelijkheden sign x | x>0 = 1 | x==0 = 0 | x<0 = -1 een functie-definitie is een expressie sign x = if x>0 then 1 else if x==0 then 0 else -1

(S)DT Schrijf nu zelf een functie quicksort voor [Int] een functie die een oneindige lijst van alle positieve oneven getallen specifieert een functie die een oneindige lijst van alle priemgetallen specifieert een functie die nagaat of een gegeven getal een priemgetal is probeer een polymorfe sort te schrijven

(S)DT Nog eens: luie evaluatie Actueel argument van een functie: uitgestelde berekening Werkt met een closure: te evalueren expressie + relevante bindingen Closures nemen plaats in op de heap (ook ints, lists, …) Call by need en call by value: zelfde antwoord als het programma eindigt MAAR nooit meer reductie-stappen want.. Soms toch waarde berekenen: wanneer?

(S)DT Stricte functies Argument van een functie: als de waarde ervan altijd nodig is, dan is de functie strict in dat argument. Voorbeeld: fact n, kwadraad i, telop x y Maar project x y = x constPi x = 3.14 Voor stricte argumenten: compiler kan beslissen toch uit te rekenen Voor niet-stricte argumenten: (keten van) closures nemen plaats op heap

(S)DT Nut van oneindige lijsten? lui? Programma: abstracter, eenvoudiger Producer + consumer toepassingen met corouting Een tijdelijke lijst wordt “on demand” opgebouwd Enkel berekenen wat nodig is voor het vinden van een oplossing

(S)DT Wat met andere functionele talen?? Stricte talen (call by value): Lisp, Scheme, ML, Erlang (concurrent) Niet-stricte/luie talen (call by need): Miranda (inspiratie voor Haskell), Hope, Clean (concurrent) Wat is het beste?? Implicaties van luiheid? Puur functioneel!!

(S)DT De lambda notatie Een functie hoeft geen naam te hebben Enkel een voorschrift om de functie te evalueren Mogelijk in Haskell met de λ-notatie voor functies plus1list = map plus1 where plus1 i = i ofwel ook plus1list = map (\x -> x+1) Meer algemeen (\a b c d -> (fib a) + (head b) * c +d ) Wat is (\x y -> x * y) 3 ?

(S)DT filter :: (t -> Bool) -> [t] -> [t] filter p [] = [] filter p (x:xs) | p x = x : rest | otherwise = rest where rest = filter p xs Miranda Lisp, ML, Scheme filter = \p -> \xs -> case xs of [] -> [] (x:xs) -> let rest = filter p xs in if (p x) then x : rest else rest

(S)DT Lijsten van gehele getallen Alsof Haskell vooraf definieerde: [n..m] = if n > m then [] else n : [ (n+1).. m] [i..] = (i : [(i+1).. ]) dus Main> [3..8] [3,4,5,6,7,8] Main> [-5..1] [-5,-4,-3,-2,-1,0,1] Main> take 4 [21..] [21,22,23,24]

(S)DT Functie samenstelling filterpos::[Int] -> [Int] filterpos [] = [] filterpos (x:xs) | x > 0 = x : filterpos xs | otherwise = filterpos xs suml :: [Int] -> Int suml [] = 0 suml (x:xs) = x + suml xs addpos l = suml (filterpos l) addpos2 = suml. filterpos -- suml na filterpos addpos3 = suml. (filter (>0)) addpos4 = foldr (+) 0. filter (>0)

Functie samenstelling Prelude> :t (.) (.) :: (b -> c) -> (a -> b) -> a -> c (f.g) x = f ( g x) foldr :: (a->b->b) -> b -> [a] -> b it takes the second argument and the last item of the list and applies the function, then it takes the penultimate item from the end and the result, and so on. See scanr for intermediate results.scanr Input: foldr (+) 5 [1,2,3,4] Output: (1 + ( 2 + (3 + (4 +5)))) Input: scanr (+) 5 [1,2,3,4] Output: [15,14,12,9,5] (S)DT

(S)DT Haskell: einde deel 1 wordt vervolgd….