(S)DT 2012-2013 1 Haskell Deel 2 list comprehensions, types en type klassen, programma transformatie, I/O.

Slides:



Advertisements
Verwante presentaties
KINN 2010 •OOP •O Object •O Georiënteerd •P Programmeren.
Advertisements

Deel I: Functionele Programmeertalen Hoofdstuk 4: Functioneel Programmeren.
Uitwerking tentamen Functioneel Programmeren 29 januari 2009.
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.
Het type int Tekenen met Java operatoren
Hogeschool HZ Zeeland 19 augustus 2003augustus 2003 Data Structuren & Algoritmen Week 5.
Hoofdstuk 6: Controle structuren
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.
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.
Inleidend probleem Data structuur (hiërarchie van classes)
Functies als Getallen Jan Martin Jansen.
Numerieke Natuurkunde
Flow controle Keuzes maken. Het if-statement Soms moet code alleen in bepaalde situaties uit gevoerd worden Hiervoor heeft C de if-else constructie: if(voorwaarde1){
-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.
1 Datastructuren Heapsort (2e deel) College 5. 2 Vandaag  Heaps en Heapsort  (eind)  Nog sneller sorteren:  Ondergrenzen  Linair sorteren.
Imperatief programmeren nProgramma bestaat uit nRunnen is opdrachten gegroepeerd in methoden één voor één uitvoeren te beginnen met main.
Ontleden nNon-deterministisch m.b.v. Parser-combinators nDeterministisch m.b.v. Stack-machine type Parser a b = [a]  [ (b, [a]) ] type Parser a b = [a]
Functioneel Programmeren Daan Leijen. Wat gaan we doen? 3 fundamentele principes van computatie Equationeel redeneren IO-monad GUI's in Haskell (wxHaskell)
Static Keyword static voor functieleden functie niet voor een object aangeroepen class K {... static int minimum( int i, int j); } aanroep: K::minimum(
JAVA -- H51 CONSTRUCTOR –- COPY-CONSTRUCTOR 1Constructor: Dezelfde naam als de klasse Wordt uitgevoerd d.m.v. new Initialisatie van de (private) attributen.
Algoritmiek Object-georiënteerd Programmeren
P. 1 Vakgroep Informatietechnologie Structuur Deel II C++ Classes Namespaces Type casting Reference types Constructors en Destructors Memory Management.
P. 1 Deel I: Programmeertaal C 4. Functies en Macro’s Prof.Dr.Ir. Filip De Turck.
LauwersCollege Buitenpost Java Applet programma dat op een website zichtbaar is Java Application programma dat zelfstandig werkt Javascript Scripttaal.
Eenvoudig voorbeeld: Steden in Belgie
KINN 2010 OOP O Object O Georiënteerd P Programmeren.
Introductie tot GoF patterns in Java
Tircms03-p les 2 Hfdst 3,4 Meer operatoren Functies.
Tentamen vraag 1 Als L en M talen zijn, dan nL  M is gelijk aan { s  t | s  L, t  M } nL M is gelijk aan { s t | s  L, t  M } nL n is gelijk aan.
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 1 Operating Systems practicum
Intermezzo: Queries op zoekbomen Datastructuren. Queries: hoe op te lossen We hebben: – Een zoekboom (gewoon, rood-zwart, AVL,…) – Een vraag / querie.
Tircms03-p les 4 Klassen. Abstracte datatypes in C struct stack { char info[100]; int top; }; void reset(stack *s) { s->top = -1; } void push(stack *s,
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.
Vervolg C Hogeschool van Utrecht / Institute for Computer, Communication and Media Technology 1 Onderwerpen voor vandaag top-down decompositie Opdrachten:
(S)DT Haskell Functioneel programmeren.
Definitie Taal van een grammatica nZij grammatica G = ( T, N, R, S ) nde taal van G is { z  T* | S  * z } L(G)
Java Objectgeoriënteerd Programmeren in Java met BlueJ Hoofdstuk 7 Polymorfie en overerving © 2014, Gertjan Laan, versie 2.
 C++ heeft een inheritance mechanisme  Manier om functionaliteit te ‘erfen’ van een parrent class ◦ Polymorphisme ◦ Zoals we het ook in C# kennen.
Hoorcollege 1: efficiëntie en complexiteitsontwikkeling.
Codetuts Academy Les 6 Module 2a Php Fundamentals 1.
Les 3 - Operators Workshop Php Basic. ICT Academy Php Basic Content Operators Wiskundig Toewijzing Vergelijking.
Loops en errors Array's Random try catch for loop while loop do while loop.
Na de praktijk, de theorie.. Zoals een gehaktmolen 1.Je stopt er iets in. 2.Je hoeft niet te weten wat er binnenin gebeurt. 3.Het resultaat verschijnt.
GUI & classes Een Gui in een class steken en het object gebruiken.
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.
De definitie van een object. Een object is een verzameling van eigenschappen en bewerkingen. Veel voorkomende objecten zijn: D (display) Gui (user interface)
Informatie beoordelen If else Switch En Wiskunde.
Berekening van de Orde Van een Algoritme
Gameprogrammeren: Objecten en geheugen
Gameprogrammeren: Lists en interfaces
Gameprogrammeren: Expressies
Gameprogrammeren: Methoden
Tinpro015b-les 1 C++ voor C-kenners Voor Technische Informatica.
Tinpro015b-les3 Hfdst 3,4 Meer operatoren Functies.
Tinpro015b-les6 Templates.
Tinpro015b-les4 Klassen.
Implementatie Zoekboom
TOP met iTasks 2.
Gameprogrammeren: Arrays
Python – For loop + strings
Transcript van de presentatie:

(S)DT Haskell Deel 2 list comprehensions, types en type klassen, programma transformatie, I/O

LIST COMPREHENSIONS (S)DT

3 List comprehension Main> [ 2*a | a <- [2,3,8] ] [4,6,16] lezen we als de lijst met waarden 2*a met a geselecteerd uit de lijst [2,3,8] -- <- generator l = take 10 [ x*x | x <- (odds [1..])] where odds [] = [] odds (x:xs) | x `mod` 2 == 1 = (x : odds xs) | True = (odds xs) Main> l [1,9,25,49,81,121,169,225,289,361]

(S)DT Nog list comprehensions Main> let l = [2,4,7] in [ a > 4 | a <-l] [False,False,True] Main> let l = [8,2,4,7] in [a | a 4] [8,7] -- generator en test Main> take 10 [ x*x | x <- [1..], x `mod` 2 == 1] [1,9,25,49,81,121,169,225,289,361] Main> let l= [ [], [1], [4,5], []] in [ a | (a:x) <-l] [1,4] Main> let l = [ (1,2), (4,3)] in [ a+b| (a,b) b] [7]

(S)DT Variabelen in list comprehensions Main> let l = [(1,2), (4,3)] in [b | (1,b) <- l] [2] Main> let l = [(1,2), (3,3)] in [b | (b,b) <- l] ERROR - Repeated variable "b" in pattern -- scope van variabelen f x l = [ a | (x,a) <- l] -- nieuwe x g x l = [ a | (y,a) <- l, x == y] Main> f 1 [(1,2), (4,3)] [2,3] Main> g 1 [(1,2), (4,3)] [2]

(S)DT Verschillende generatoren Main> [ (a,b) | a <- [1..2], b <- [1..3]] [(1,1),(1,2),(1,3),(2,1),(2,2),(2,3)] Main> [ (a,b) | b <- [1..3], a <- [1,2]] [(1,1),(2,1),(1,2),(2,2),(1,3),(2,3)] Main> let l = [(2,7), (4,3)] -- b is afhankelijk in [(a,b)| (a,_) <- l, b <- [1..a]] [(2,1),(2,2),(4,1),(4,2),(4,3),(4,4)] -- Een Pythagorees drietal (a, b, c) bestaat uit drie positieve gehele getallen a, b, c met a < b < c waarvoor geldt a 2 + b 2 = c 2positievegehele getallen

(S)DT Algemene vorm [ e | q1, q2, …, qn] qi is (pattern <- listexpr) of (boolean expr) vars in qi moeten links ervan voorkomen elke var in een pattern is nieuw! Schrijf map f (filter p xs) nu met list comprehension En eventueel ook qsort

(S)DT Opnieuw priem priemgetallen n = [ x | x <- [1..n], priem x] priem x = factors x == [1,x] factors n = [ x | x <- [1..n], n `mod` x == 0]

TYPES Data declaraties; Polymorfe types; Type klassen (S)DT

10 Welke types kennen we? Int, Integer [Int] (Bool, Int) type variabele t,a,b lengthlist :: [t] -> Int map :: (a->b) -> [a] -> [b] Char ‘a’ String “hallo world” in feite synoniem voor lijst van Char type String = [Char] type Positie = (Int,Int)

(S)DT Data declaratie voor type IBoom data IBoom = Knoop IBoom IBoom | Blad Int -- wat zijn de mogelijke waarden van het type IBoom? -- Knoop (Blad 4) (Knoop (Blad 3) (Blad 100)) balanced :: IBoom -> Bool balanced (Knoop left right) = let l = diepte left r = diepte right in (ok l r ) && (balanced left) && (balanced right) balanced (Blad _) = True ok :: Int -> Int -> Bool ok l r = (l==r) || (l == (r+1)) || ( (l+1) == r)

(S)DT diepte :: IBoom -> Int diepte (Knoop l r) = 1 + maxi (diepte l) (diepte r) diepte (Blad _) = 1 maxi :: Int -> Int -> Int maxi x y | x > y = x | otherwise = y

(S)DT Ingebouwde types data Bool = True | False -- enumeratie -- Bool is een nieuw type met 2 mogelijke waarden -- constructor-functies: True en False data Int = 0 | 1 | -1 | 2 | -2 | 3 …

(S)DT Meer types Record type data Punt = Coord Int Int -- Coord als data constructor data Punt = Punt Int Int -- Verschil?? data Punt = MkPunt Int Int -- Verschil?? Hoe: Int of Bool Constructors worden gebruikt:  Als een functie om waarden aan te maken (in rechter deel van equations)  In patronen om waarden af te breken (in linker deel van equations)

(S)DT Polymorfe types data Boom a =Knoop (Boom a) (Boom a)|Blad a Voor elk type a is (Boom a) een data type Boom is een typeconstructor Knoop is een dataconstructor – of een constructor functie Main> :t Knoop Knoop :: Boom a -> Boom a -> Boom a Main> :t Blad Blad :: a -> Boom a

(S)DT Bladeren bladeren :: Boom a -> [a] bladeren (Knoop l r) = bladeren l ++ bladeren r bladeren (Blad b) = [b] -- Nog een ingebouwd (polymorf) datatype … data [a] = [] | a : [a]

(S)DT Werkvoorbeeld polymorfisme isort :: [Int] -> [Int] isort [] = [] isort (x:xs) = insert x (isort xs) insert :: Int -> [Int] -> [Int] insert x [] = [x] insert x (y:ys) | x<y = x:y:ys | otherwise = y : (insert x ys) -- polymorfe versie?? door ??? -- Int vervangen door ???

(S)DT Polymorfe isort isort :: (t -> t -> Bool) -> [t] -> [t] isort _ [] = [] -- was isort (x:xs) = insert x (isort xs) isort orde (x:xs) = insert orde x (isort orde xs) insert :: (t -> t -> Bool) -> t -> [t] -> [t] insert _ x [] = [x] insert orde x (y:ys) | (orde x y) = x:y:ys | otherwise = y : (insert orde x ys) Main> isort (<) [3,1,7] [1,3,7]

(S)DT Evaluatie: wat gedaan? extra parameter (de functie) doorgeven – eventueel diep de type declaraties aanpassen code aanpassen de waarde van die parameter is gekend op moment van de topoproep de waarde (naam van de functie) kan afhankelijk zijn van het type Misschien is het handiger om uit te drukken:  isort mag enkel op een lijst met elementen waarop (<) gedefineerd is

(S)DT Overloading wat is overloading?? ad-hoc polymorfisme voorbeeld : een zelfde operator + kan gebruikt worden voor verschillende types van operanden (Int, Float) en de definitie van + is type-afhankelijk dezelfde naam maar verschillende operaties op verschillende types wat is het type van square n = n*n ?

(S)DT Type classes: uitbreidbare overloading class HeeftOrde a where -- klasse-declaratie ( a -> Bool isort :: (HeeftOrde t) => [t] -> [t] -- klasse-constraint isort [] = [] isort (x:xs) = insert x (isort xs) insert :: (HeeftOrde t) => t -> [t] -> [t] insert x [] = [x] insert x (y:ys) | x <<< y = x:y:ys | otherwise = y: (insert x ys)

(S)DT Klasse-constraint insert :: (HeeftOrde t) => t -> [t] -> [t] insert x [] = [x] insert x (y:ys) | x <<< y = x:y:ys | otherwise = y: (insert x ys) zonder klasse-constraint zegt Haskell: ERROR "cl.hs":12 - Cannot justify constraints in explicitly typed binding *** Expression : insert *** Type : a -> [a] -> [a] *** Constraints : HeeftOrde a Main> isort [2,1] ERROR - Unresolved overloading *** Type : (Num a, HeeftOrde a) => [a] *** Expression : isort [2,1]

(S)DT Instance van een klasse data Dagen = Maan | Dins | Woen | Dond |Vrij instance HeeftOrde Dagen where Maan <<< _ = True _ <<< Maan = False Dins <<< _ = True _ <<< Dins = False Woen <<< _ = True _ <<< Woen = False Dond <<< _ = True _ <<< _ = False Main> isort [Maan, Woen, Dins] [Maan,Dins,Woen]

(S)DT Dus nu met type classes geen extra parameters geen code aanpassen type declaratie aanpassen – eventueel diep het type van de polymorfe parameter is gekend op moment van de topoproep de compiler kan achter de schermen de vergelijkingsfunctie meegeven (en doet dat) de naam van de functie is voor alle instances van de klasse dezelfde. Gelijkenis met interface van Java?

(S)DT Wat hebben we? Een type klasse is een groep van types (instances) waarop bepaalde functies kunnen worden toegepast (vergelijk met polymorf type) Type klassen laten toe om de parameters van de polymorfe types/functies verder te beperken Bv. type parameter a, maar == gedefinieerd voor a Type klassen en instanties worden gebruikt voor het checken van de types tijdens compilatie. Type klassen hiërarchie: class (Eq a) => Ord a where … -- Ord is een subklasse, erft van Eq

(S)DT Dus Een type klasse beschrijft een “concept” Een type kan een instance zijn van een type klasse en is dan een implementatie van het “concept”. Generische programma’s mogelijk dankzij  Parametrisch polymorfisme  Type constraints (zie context) In Java, concept als “interface” En een Java class implements interface

(S)DT Ingebouwde klassen uit Prelude class Eq a where (==), (/=) :: a -> a -> Bool x /= y = not (x==y) -- default definitie class (Eq a) => Ord a where -- class extension compare :: a -> a -> Ordering ( =), (>) :: a -> a -> Bool compare x y | x == y = EQ | x <= y = LT | otherwise = GT x <= y = compare x y /= GT x < y = compare x y == LT

(S)DT Ingebouwde instanties data Bool = False | True instance Eq Bool where True == True = True False == False = True _ == _ = False instance Ord Bool where False <= True = True _ <= _ = False

(S)DT Eenvoudig instanties maken Er is dikwijls een natuurlijke implementatie voor de functies in een klasse data Bool = False | True deriving (Eq, Ord, Show, … ) Is elk type een instance van Eq? Door er deriving Eq bij te zetten? Waarom mag dezelfde variabele niet tweemaal in een pattern match?

(S)DT De klasse Num class (Eq a, Show a) => Num a where (+), (-), (*) :: a -> a -> a negate :: a -> a abs, signum :: a -> a fromInteger :: Integer -> a fromInt :: Int -> a x - y = x + negate y fromInt = fromIntegral negate x = 0 - x Main> :t square square :: Num a => a -> a

(S)DT Int als instance van Num -- Int is builtin datatype of fixed size integers primitive primEqInt :: Int -> Int -> Bool instance Eq Int where (==) = primEqInt instance Num Int where (+) = primPlusInt -- ingebouwd prim… (-) = primMinusInt negate = primNegInt fromInteger n = n

(S)DT Type klassen en type inferentie De type inferentie leidt het meest algemene type af. Daarin komen dikwijls type constraints voor (+) :: Num a => a -> a -> a (/) :: Fractional a => a -> a -> a

(S)DT Instances met voorwaarden -- data [a] = [] | a : [a] deriving (Eq, Ord) instance Eq a => Eq [a] where -- context!! [] == [] = True (x:xs) == (y:ys) = x == y && xs == ys -- welke? _ == _ = False

(S)DT de klasse Text ERROR - Cannot find "show" function for: *** Expression : isort [Maan,Woen,Dins] *** Of type : [Dagen] class Show a where show :: a -> String data Dagen = Maan | Dins | Woen | Dond |Vrij deriving Show Main> show Maan “Maan”

(S)DT Enkele vragen Wat is het meest algemene type van elem 1 [ 2, 4, 9] False elem ‘a’ “Harry” True En van allevk a [] = [] allevk a ((x,y): rest) = if a == x then y : allvk a rest else allevk a rest En van qsort ??

(S)DT Nog enkele vragen Herinner je het type Boom a data Boom a = Knoop (Boom a) (Boom a)| Blad a  Hoe een gelijkheidstest definieren?  Type declaratie van de functie element?? Eindige set (wat is een set??) voorgesteld als een lijst  Type declaratie  Voegtoe, unie, element?  Gelijkheid van 2 sets?

Meer info over classes In TasteofHaskell.pdf : slides (S)DT

PROGRAMMA TRANSFORMATIE Equational reasoning (S)DT

(S)DT reverse en reverse nrev [] = [] nrev (x:xs) = nrev xs ++ [x] [] ++ l = l (x:xs) ++ l = (x : (xs ++ l)) reverse l = rev2 l [] rev2 [] a = a -- (a) rev2 (x:xs) a = rev2 xs (x:a) -- (b) nrev is O( n**2) – reverse is O(n)

(S)DT Automatisch van nrev naar reverse vertrek van de invariant voor alle l : rev2 l a = (nrev l) ++ a gebaseerd op het type van l, herschrijf tot: voor l== [] of l==(x:xs): rev2 l a = (nrev l) ++ a of zonder quantoren 1. rev2 [] a = (nrev [] ) ++ a 2. rev2 (x:xs) a = (nrev (x:xs)) ++ a we bewijzen achtereen volgens (a) en (b)

(S)DT Te bewijzen: rev2 [] a = a rev2 [] a = (nrev []) ++ a -- (1) = [] ++ a -- gebruik 1ste regel nrev = a -- 1ste regel van ++ We hebben (a) bewezen en gebruikten de invariant en partiële evaluatie

(S)DT Te bewijzen rev2 (x:xs) a = rev2 xs (x:a) rev2 (x:xs) a = (nrev (x:xs)) ++ a -- (2) = ( (nrev xs) ++ [x]) ++ a -- gebruik 2e regel nrev = (nrev xs) ++ ([x] ++ a) is associatief = (nrev xs) ++ (x : a) -- regels van ++ = rev2 xs (x:a) -- invariant omgekeerd We hebben (b) bewezen en gebruikten de invariant en partiële evaluatie en de associativiteit van ++ (nog te bewijzen)

(S)DT Te bewijzen (a ++ b) ++ c = a ++ (b ++ c) Inductie op lengte van a: a kan [] zijn of (x:xs) Basis van de inductie: a = [] ([] ++ b ) ++ c = b ++ c -- regel 1 van ++ Inductiestap: stel associativiteit is waar voor a == xs, bewijs dat associatviteit is waar voor a = (x:xs)

(S)DT Associativiteit: inductiestap x:xs 2e regel : (x:xs) ++ l = (x : (xs ++ l)) (a ++ b ) ++ c = ( (x:xs) ++ b) ++ c -- a == (x:xs) = ( x : (xs ++ b) ) ++ c -- regel 2 van ++ = x : ( (xs ++ b) ++ c) -- regel 2 van ++ = x : ( xs ++ (b ++ c)) -- asso. Door inductie = (x : xs) ++ (b ++ c) -- omgekeerde regel 2 ++ = a ++ (b ++ c) -- a == (x:xs)

I/O HASKELL (S)DT

(S)DT I/O in pure Haskell heeft geen zin want  referential transparency: 2x oproepen, 2x zelfde resultaat  luiheid: op welk ogenblik wordt een functie uitgevoerd? Hoe zinvol aan I/O doen in Haskell?  de toestand van de wereld is een impliciet argument van functies die I/O doen  sequentialisatie van I/O acties

(S)DT I/O ondersteuning door type systeem en nieuwe syntactische constructie – do getChar :: IO Char putChar :: Char -> IO () Een waarde van type IO t is een “action” die, als ze wordt uitgevoerd, mogelijks wat I/O doet voor een resultaat van type t te geven. Dus wat leiden we af uit het type van putChar ?

Achterliggend idee Een waarde van type IO t is een “action” die, als ze wordt uitgevoerd, mogelijks wat I/O doet voor een resultaat van type t te geven. type IO t = World -> (t,World) -- een benadering!!! (S)DT World inWorld out I/O t result :: t

(S)DT Voorbeeld I/O en do-notatie Een functie die een Int als argument heeft, IO doet en een string teruggeeft: n chars worden gelezen en omgekeerd als string teruggegeven foo :: Int -> IO String foo n = do a <- getnchars n [] return a getnchars :: Int -> String -> IO String getnchars 0 l = return l getnchars (n+1) l = do a <- getChar s <- getnchars n (a:l) return s -- return :: a -> IO a -- do maakt 1 actie van een sequentie van acties

(S)DT Een functie f doet IO f heeft als return type IO iets als g f oproept, dan doet g IO en heeft type IO iets’ f roept minstens 1 functie op die IO doet en kan functies oproepen die dat niet doen waarde van iets kan opgevangen worden door de constructie <- do dient om IO te sequentialiseren

(S)DT Voorbeeld opnieuw foo :: Int -> IO String foo n = do a <- getnchars n return (rev a) getnchars :: Int -> IO String getnchars 0 = return [] getnchars (n+1) = do a <- getChar s <- getnchars n return (a:s)

(S)DT Waarden van het type (IO t) zijn first class forever :: IO () -> IO () forever a = do { a; forever a } repeatN :: Int -> IO () -> IO () repeatN 0 a = return () repeatN n a = do { a; repeatN (n-1) a } Main > repeatN 10 (putChar ‘x’)

(S)DT Lui en I/O … vergelijk f = let x = (error) in 3 g = do x <- getnchars (error) [] return 3 Main> f 3 Main> g Program error: error

(S)DT N-queens interactief qs :: IO () qs = do i <- readi schrijf (queens i) schrijf :: Show a => [a] -> IO () schrijf [] = return () schrijf (x : xs) = do putStr “\n” c <- putStr (show x) schrijf xs -- Main> :t show -- show :: Show a => a -> String -- Main> :t () trivial type -- () :: ()

(S)DT readi :: IO Int readi = riacc 0 riacc :: Int -> IO Int riacc acc = do x <- getChar if ( (tr x) < 0) then return acc else do z <- (riacc ((10* acc) + (tr x))) return z tr ‘0’ = 0 … tr ‘9’ = 9 tr _ = -1

(S)DT Main> qs 4 [3,1,4,2] [2,4,1,3] Main> qs 6 [5,3,1,6,4,2] [4,1,5,2,6,3] [3,6,2,5,1,4] [2,4,6,1,3,5]

Doing “timings” import CPUTime main :: IO Int main = do t1 <- getCPUTime let f1 = fib(21) print f1 -- forceert de oproep van fib t2 <- getCPUTime print "uitvoeringstijd : " print (t2-t1) -- in picoseconden (10 -12) return f1 {- oproep Main> do { a<- main; print a } "uitvoeringstijd : " -} (S)DT

(S)DT De klasse Show data Itree = Leeg | Node Itree Int Itree instance Show Itree where -- showsPrec :: Int -> a -> (String -> String) showsPrec n Leeg = ([]++) showsPrec n (Node t1 i t2) = let n1 = n+1 ni = n+i in (showsPrec n1 t1).((show ni)++).(showsPrec n1 t2) -- show x = showsPrec 0 x “” Main> show (Node (Node Leeg 23 Leeg) 5 Leeg) “245”

(S)DT In feite: I/O Monad Haskell maakt gebruik van monads om berekeningen met waarden te structureren: bijvoorbeeld te sequentialiseren. I/O is in feite ook zo’n monad en de do- syntax kan gebruikt worden voor monads. Nog een monad: berekening die kan falen data Maybe a = Nothing | Just a In Prelude class Monad m where …

(S)DT Haskell: einde deel 2