TENTAMEN I DVA 229 FUNKTIONELL PROGRAMMERING MED F# Torsdagen den 8 juni 2017, kl 14:10 – 18:30 Kurslitteratur är inte tillåten, och inte eller andra hjälpmedel som på något sätt kan ersätta kurslitteraturen (t.ex. egna anteckningar, andra böcker i ämnet, kopior av OH-bilder, datorer eller räknare med dito lagrad information). Endast generella hjälpmedel är tillåtna, som räknare utan lagrad information av betydelse för kursen, ordbok, allmän formelsamling och liknande. För godkänt krävs 15 poäng, max är 30 poäng. Resultatet offentliggörs senast torsdagen den 29 juni 2017. Vänligen observera följande: • Motivera alltid dina svar. Bristande motivering kan ge poängavdrag. Omvänt kan även ett felaktigt svar ge poäng, om det framgår av motiveringen att tankegången ändå är riktig. • Skriv tydligt! • Varje blad skall vara försedd med uppgiftsnummer och bladnummer. • Endast en uppgift på ett och samma blad. • Skriv enbart på ena sidan av ett blad. • Uppgifterna är inte nödvändigtvis sorterade i svårighetsgrad. Om du kör fast kan det löna sig att gå vidare till nästa uppgift. • Lösningsförslag kommer att finnas på kursens hemsida efter att tentan är slut. Frågor: Björn Lisper på 021-151709. UPPGIFT 1 (6 POÄNG) I den här uppgiften ska du deklarera en funktion times3 som tar en lista med element och returnerar en tre gånger så lång lista av där varje element i argumentlistan är upprepad tre gånger. T.ex. ska gälla att times3 [1;2;3] = [1;1;1;2;2;2;3;3;3]. times3 ska kunna hantera listor med element av godtycklig typ. a) Deklarera en version av times3 som använder direkt rekursion!. (3p) b) Vad får din version av times3 för typ?. (Du behöver inte härleda typen, det räcker med att ange den.) (1p) c) Gör en alternativ deklaration av times3 som använder sig av någon eller några av de inbyggda högre ordningens funktionerna i F# på ett vettigt sätt. (2p) UPPGIFT 2 (4 POÄNG) Deklarera en funktion som tar en lista av heltal (av typ int) och som sidoeffekt skriver ut elementen i listan enligt följande: Element 1: ... Element 2: ... ... Element n: ... För den tomma listan ska funktionen skriva ut ett radbyte. För listan [3,4,5] ska alltså utskriften bli Element 1: 3 Element 2: 4 Element 3: 5 1 Lös uppgiften med rekursion. UPPGIFT 3 (3 POÄNG) a) Förklara kortfattat skillnaden mellan lat evaluering (call-by-need) och ivrig evaluering (call-by-value)! Visa ett exempel där de ger olika resultat. (2p) b) Har F# lat eller ivrig evaluering som default? (1p) UPPGIFT 4 (5 POÄNG) Deklarera en funktion som tar en sträng innehållande tecknen ’0’ och ’1’, tolkar dem som binärrepresentationen av ett heltal och returnerar detta heltal! Den mest signifikanta biten ska ligga längst till vänster. Exempelvis ska strängen "1101" översättas till heltalet 13, av typ int. Om strängen är tom ska heltalet 0 returneras. Om det finns något tecken i strängen som inte är ’0’ eller ’1’ ska ett felavbrott ske. Lösningen ska använda rekursion utan sidoeffekter (inga muterbara variabler eller liknande) och får inte använda sig av några inbyggda konverteringsfunktioner eller liknande. UPPGIFT 5 (2 POÄNG) Betrakta följande F#-deklarationer: let f x = [x;x+1] let g = fun x -> [x;x+1] Blir det någon skillnad på funktionerna f och g och i så fall vilken? UPPGIFT 6 (6 POÄNG) Svartvita bilder går att representera på smartare sätt än som en matris av pixlar. Istället kan man använda en trädrepresentation som rekursivt bryter ner bilden i mindre och mindre kvadrater tills kvadraterna helt innehåller en svart yta. En kvadratisk bild delas då upp i fyra lika stora kvadrater där sidan för varje delkvadrat är halverad jämfört med den ursprungliga kvadraten, och sen delar man rekursivt upp dessa i fyra mindre kvadrater, och så vidare. När en kvadrat innehåller en helt svart yta bryter man den rekursiva uppdelningen. Se figuren nedan. Denna representation kan vara betydligt kompaktare än en pixelmatris, speciellt för bilder som innehåller stora sammanhängande ytor med samma färg. a) Deklarera en datatyp för träd som erpresenterar svartvita, kvadratiska bilder enlgt ovan! (2p) b) Deklarera en funktion som tar en trädrepresentation av en bild och räknar ut hur stor andel av bilden som är svart! (4p) UPPGIFT 7 (4 POÄNG) Funktionen foo definieras av let rec foo l = match l with | [] -> () | x::xs -> x ; foo xs 2 Härled en typ för foo! För full poäng ska den härledda typen vara den mest generella. Ordentlig motivering krävs. (4p) Ledning: operatorn “;” har typen unit -> ’a -> ’a. Lycka till! 3 Björn