Enjoy Vattenfallsmodellen i funktionella språk

Relevanta dokument
Enjoy Vattenfallsmodellen i funktionella språk

DD1361 Programmeringsparadigm. Carina Edlund

Föreläsning 5 i programmeringsparadigm.

Föreläsning 4 (och 5?) i programmeringsparadigm.

SMD 134 Objektorienterad programmering

Föreläsning 3: Booleans, if, switch

Datatyper och kontrollstrukturer. Skansholm: Kapitel 2) De åtta primitiva typerna. Typ Innehåll Defaultvärde Storlek

Programmering med Java. Grunderna. Programspråket Java. Programmering med Java. Källkodsexempel. Java API-exempel In- och utmatning.

Föreläsning 4 (och 5?) i programmeringsparadigm.

Objektorienterad Programmering (TDDC77)

I Skapa Hej.java och skriv programmet. I Kompilera med javac Hej.java. I Rätta fel och repetera tills du lyckas kompilera ditt program

Föreläsning 6 i programmeringsparadigm. Tips kring programmering i Haskell och kring labbarna.

Föreläsningar 7,8 sept 24, sept 26 v 39). delvis DD Chapter 6.

Introduktion till programmering SMD180. Föreläsning 4: Villkor och rekursion

Kompilering och exekvering. Föreläsning 1 Objektorienterad programmering DD1332. En kompilerbar och körbar java-kod. Kompilering och exekvering

Metodanrop - primitiva typer. Föreläsning 4. Metodanrop - referenstyper. Metodanrop - primitiva typer

Introduktion till Haskell

Föreläsning 5 i programmeringsparadigm. Tips kring programmering i Haskell och kring labbarna.

(Man brukar säga att) Java är... Denna föreläsning. Kompilering av Java. Historik: Java. enkelt. baserat på C/C++ Allmänt om Java

Programmering A. Johan Eliasson

Funktionell programmering DD1361

732G Linköpings universitet 732G11. Johan Jernlås. Översikt. Repetition. Felsökning. Datatyper. Referenstyper. Metoder / funktioner

TDIU01 - Programmering i C++, grundkurs

Objektorienterad Programmering (TDDC77)

TDDC77 Objektorienterad Programmering

Introduktion till Datalogi DD1339. Föreläsning 2 22 sept 2014

Klassdeklaration. Metoddeklaration. Parameteröverföring

Undervisning. Examination

Några inbyggda funktioner (med resultat!) Introduktion till programmering D0009E. Föreläsning 4: Villkor och rekursion. Modulus-operatorn.

Introduktion till programmering SMD180. Föreläsning 2: Variabler, uttryck och satser

Programmera i C Varför programmera i C när det finns språk som Simula och Pascal??

Föreläsning 4 i programmeringsparadigm.

732G Linköpings universitet 732G11. Johan Jernlås. Översikt. Repetition. Muddy. Funktioner / metoder. Punktnotation. Evalueringsordning

ITK:P1 Föreläsning 1. Programmering. Programmeringsspråket Java. Stark typning Explicit typning Strukturerat Hög säkerhet

F4. programmeringsteknik och Matlab

Del : Funktionell programmering. I alla deluppgifterna, använd Haskell och skriv typen för de identifierare du definierar.

Datastrukturer. Erik Forslin. Rum 1445, plan 4 på Nada

Föreläsning 9 i programmeringsparadigm. Paradigmöversikt, paradigmhistoria, paradigmgeografi. Se även föreläsning 1.

Vem är vem på kursen. Objektorienterad programvaruutveckling GU (DIT011) Kursbok Cay Horstmann: Big Java 3rd edition.

Del : Paradigmer allmänt.

Tentamen. Datalogi I, grundkurs med Java 10p, 2D4112, Lördagen den 30 november 2002 kl , salar E33, E34

Hej Då, Karel! Programmering. Vårt första Javaprogram. hh.se/db2004. Java. Grundtyper, variabler och arrayer

Funktionell programmering. Haskell. Ge#ng started...

Programmeringsteknik med C och Matlab

Föreläsning 2 sept 05 (Onsdag v 36). DD Chapter 2.

TDDC30. Kursledning Kursledare: Jonas Lindgren. Labassistent: Jonas Lindgren Labassistent: Niklas Holma Labassistent: Erik Nilsson

Grundkurs i programmering, 6 hp (725G61) Dugga 2 tillfälle 2

Idag. Javas datatyper, arrayer, referenssemantik. Arv, polymorfi, typregler, typkonvertering. Tänker inte säga nåt om det som är likadant som i C.

Rekursion och induktion för algoritmkonstruktion

Parameteröverföring. Exempel. Exempel. Metodkropp

Objektorienterad programmering. Fält som funktionsresultat. Mer om fält: att uppdatera ett parameterfält. Kontrast: Parametrar av primitiv typ

Command line argumenter. Objektorienterad Programmering (TDDC77) Vad blir resultatet? Nu då? Ahmed Rezine. Hösttermin 2016

Objektorienterad Programmering (TDDC77)

Introduktion till programmering D0009E. Föreläsning 1: Programmets väg

Föreläsning 8. Paradigmöversikt, paradigmhistoria, paradigmgeografi. Se även föreläsning 1.

Övning2. Variabler. Data typer

Föreläsning 8. newtype Chess = Chess [(Square, Chessman)] -- data ist f newtype OK -- data istället för newtype krävs om >1 konstruerare.

//Använd main som ett "handtag" för att hålla ihop programmet. //Själva programmet finns i övriga klasser.

Programstruktur och terminologi. Programmet producerar följande utskrift i terminalfönstret: Ett Javaprogram består av en eller flera klasser

Föreläsning 2 Programmeringsteknik och C DD1316. Mikael Djurfeldt

Classes och Interfaces, Objects och References, Initialization

F5 Selektion och iteration. ID1004 Objektorienterad programmering Fredrik Kilander

Föreläsning 3-4 Innehåll

Algoritmanalys. Genomsnittligen behövs n/2 jämförelser vilket är proportionellt mot n, vi säger att vi har en O(n) algoritm.

F2 Datatyper och variabler. ID1004 Objektorienterad programmering Fredrik Kilander

Undervisning. Examination

Classes och Interfaces, Objects och References Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

Tentamen OOP

TENTAMEN PROGRAMMERINGSMETODIK MOMENT 2 - JAVA, 4P

Programmering B med Visual C

Föreläsning 10 Datalogi 1 DA2001. Utskrift på skärmen. Syntax. print( Hej ) Hur är det? Hej. print( Hej,end= ) print( Hur är det? ) HejHur är det?

Föreläsning 2. Täcker material från lektion 1, 2, 3 och 4:

Grundläggande programmering med C# 7,5 högskolepoäng

Introduktion till programmering. Undervisning. Litteratur och examination. Lärare. Föreläsning 1

Bankkonto - övning. Övning 2 Skriv en metod, geträntan, som returnerar räntan.

TDIU01 - Programmering i C++, grundkurs

Föreläsning 3: Typomvandling, villkor och val, samt textsträngar

Föreläsning 3-4 Innehåll. Diskutera. Metod. Programexempel med metod

Användarhandledning Version 1.2

OOP Objekt-orienterad programmering

Imperativ programmering. Föreläsning 2

Introduktion till programmering SMD180. Föreläsning 3: Funktioner

Föreläsning 7 i programmeringsparadigm. Ytterligare Högre ordningens funktioner: filter, foldr foldl. Hutton 7.2, 7.3 och 7.4.

Att deklarera och att använda variabler. Föreläsning 10. Synlighetsregler (2) Synlighetsregler (1)

Datalogi I, grundkurs med Java 10p, 2D4112, Fiktiv tentamen, svar och lösningar och extra kommentarer till vissa uppgifter 1a) Dividera förs

Föreläsning REPETITION & EXTENTA

Föreläsning 2 Programmeringsteknik och C DD1316. Programmering. Programspråk

Nada KTH 2003 okt 23 Tentamen Programmeringsparadigm 2D1350 Skrivtid 5 h 8-13

Python. Python är, som Scheme, ett interpreterat språk men det finns kompilatorer för Python.

Anmälningskod: Lägg uppgifterna i ordning. Skriv uppgiftsnummer (gäller B-delen) och din kod överst i högra hörnet på alla papper

Typkonvertering. Java versus C

Python. Python är, som Scheme, ett interpreterat språk men det finns kompilatorer för Python.

Föreläsning 1 & 2 INTRODUKTION

D0010E. Hello world! Nedräkning. Sågtand. Övningsuppgifter i Eclipse. Skapa ett program som skriver ut "Hello world" på skärmen.

2D1311 Programmeringsteknik för Bio1 och Bio2, vt 2003 Fiktivt prov På flervalsfrågorna är endast ett svar rätt om inget annat anges i frågan! Det rik

Grundläggande datalogi - Övning 1

Outline. For. I istället för att följa det normala ordningen, man ändra den. I i Java får man inte göra hopp hur som helst

Grunderna i C++ T A. Skapad av Matz Johansson BergströmLIMY

TDIU01 - Programmering i C++, grundkurs

TDIU01 - Programmering i C++, grundkurs

Transkript:

Föreläsning 2 i Programmeringsparadigm Funktionell programmering := variabler pekare sidoeffekter ;...; Fy, fy => bugfree förståeliga korta inga "satser", bara uttryck! Enjoy Vattenfallsmodellen i funktionella språk Specifikation ofta ekvationer Design funktioner def med ekvationer Kodning funktioner def med ekvationer Högre ordningens funktioner, def med ekvationer Funktioner kan var argument till funktioner Funktioner kan var resultat till funktioner Hög abstraktionsnivå => kraftfulla språk Lat evaluering, ger oändliga datastrukturer Resultat räknas ut fört när de behövs, effektivt => kraftfulla språk T e alla namn referenser, ingen (eplicit) "pekarprogrammering" => kraftfulla språk Haskell logiskt bra typsystem => Hittar många slarvfel Haskell Typklasser => Överlagrade funktioner Haskell Moduler => Modern programutveckling ADT

Historik, geografi Fokker 1.1 C&K 1.1 (Chakravarty & Keller) När man vill tänka imperativt (simulering)? Gräns mellan paradigmer Bra begrepp? Om Hudaks bok, Fokkers bok, Chakravarty & Kellers bok Praktik : Räknedosa, Interpretern hugs ModulenPrelude Räknedose- användning laddas alltid automatiskt och innehåller många fördefinierade funkitoner,..> uttryck operatorer och typer svar skal-anrop Inladdning av skript med ytterligare definitoner, load reload av script quit..>:! emacs..>:l...hs..>:r..>:q Programmering av skript med nya definitoner som sparas på fil hugs definitioner av funktioner konstanter typer moduler klasser emacs Jag rekommenderar användning av interpretatorn hugs. Hos Fokker körs Haskell med en annan interpretator, så avsnitt 1.2 i Fokker är lite annorlunda. I C&K 2.2 används GHCi, som är mycket lik hugs. I labanvisningen för labben "Introduktion till Haskell" finns anvisningar hur man använder hugs. På föreläsningen går jag igenom hur man använder hugs med hjälp av teten och bilderna i labbanvisningen och bilden ovan. Först använder vi hugs som en räknedosa med fördefinierade funktioner och operatorer (från filen Prelude som alltid "laddas in"). Fokker använder ganska avancerade fördefinierade funktioner i 1.2 och 1.3, t e product och operatorn.. i product [1..n] och definierar genast egna funktioner såsom fac och choose och en egen operator!^! i 1, 2 och 1.3. Jag (och C&K) kommer att gå lite försiktigare fram. Men snart är det dags att skriva (definiera) egna funktioner, vilket är "att programmera" i Haskell. För att få godkänt på den här kursen: Gör..>res checkin progp04

Typer och operatorer i Haskell. Översikt av några fördefinierade (dvs de finns i "Preluden", "förspelet") datatyperna och de viktigaste operatorerna med vars hjälp vi kan bilda uttryck (Fokker 1.3.3 1. 3. 4): mod (rest vid heltalsdivision) div (heltalsdivision) + - * ^ + - / * (32 bit) Int (64 bit) Double 2 12-67 2356789-976543 + - / * går i Haskell 23.67-890.78-45.89 56.34E23 && (logiskt och, båda True) < <= > >= == /= Bool True False < <= > >= == /= < <= > >= == /= (lika med, inte lika med) Char A a 7! /65 not (logiskt inte) Det finns fler primitiva datatyper än Int för heltal, bl a Integer med "oändligt antal siffror". Det finns förutom Double ytterligare en primitiva datatyp Float för flyttal ("decimaltal"), det som skiljer är att bara 32 bit tilldelas sådan variabler i minnet i stället för 64 bitar och att antalet signifikanta siffror och största och minsta eponent är därför är mindre. Typen String : type String = [Char] Strängar kan skrivas ".." konkateneras med ++.

Definition och användning av en enkel funktion: Man skriver alltså i hugs uttryck för att få hugs att beräkna något, dvs "köra" eller eekvera. Man använder i Haskell även uttryck (epressions) i högerleden när man definierar egna funktioner. Egna funktioner får namn i en funktionsdefinition. Funktioner är ett slags värden i Haskell. I Haskell kan alla sorters värden ges namn (identifierare) som börjar på liten initial. Värden skrivs med Stor (Versal) initial eller med krumelurer, t e True, False, 12, 3:[], (2. 5). I imperativa spåk ger man ju ofta namn till delar i minnet ("variabler"), som i sin tur kan innehålla olika värden under körningens gång. Detta gör vi aldrig i fuktionell programmering. Namnen står alltid för samma sak, samma värde, hela tiden! Detta är den stora vitsen! Hur gör man om man vill definiera egna funktioner (Java : metoder som returnerar värden), och hur använder man dem, kanske gång på gång? Jo: Java Haskell Matte Definition av f: f() R R class...{ f::double->double static double f(double ) { f = + 3.0 Vi definierar f() = +3 return +3; } (I emacs fönstret) Vi kallar för (formell) parameter, i matte ofta "variabel" som ju betyder något helt annat i imperativ programmering! Märk att man inte behöver skriva parantes kring i f. Användning (anrop, applikation) av f...main(...) { utdata.println( "f(14.0) = " + f(14.0)); f 14 Vad blir f(14)? 17.0 (I hugs fönstret) Vi kallar 14.0 och 2.0 för argument (i vissa böcker aktuell parameter). Märk att man inte behöver skriva parantes kring 14.0 i f 14.0.

Ytterligare ett eempel. Herons formel : Haskell Matte Om en triangel har sidor med längderna a, b och c kan triangelns yta beräknas med Herons formel: area1 ::(Double, Double, Double) -> Double area1(a,b,c) = sqrt (p*(p-a)*(p-b)*(p-c)) where p = (a+b+c) / 2 area1 :: R3 -> R area1(a,b,c) = V p(p-a)(p-b)(p-c) där p = (a+b+c) / 2 Här ser vi på funktionen area1 som en funktion med en parameter som är en tripel med flyttal, dvs av typen (Double, Double, Double) till ett resultat som är ett flyttal, typen Double. I gymnasie-matematiken säger man ofta att area1 är en funktion med tre parametrar ("variabler"), men detta är slarvigt, en funktion har en enda parameter. Körning: Main> area1 (3.0, 4.0, 5.0) Beräkna några trianglars ytor, 6.0 t e den egyptiska triangeln med sidan 3, 4 och 5. Det vanligaste sättet att i Haskell skriva en funktion för Herons formel är dock detta: (Matematikerna Schönfinkel och Haskell Curry uppfann detta bättre sätt på 1920-talet och 1940-talet, men det har ännu inte slagit igenom ännu i matteundervisningen i skolorna): area ::Double -> Double -> Double -> Double area :: R -> R -> R -> R area a b c = sqrt( p*(p-a)*(p-b)*(p-c)) area a b c = V p(p-a)(p-b)(p-c) where p = (a+b+c) / 2 där p = (a+b+c) / 2 Detta sätt att skriva är ganska ovant, och i början kan du se detta som ett sätt att i Haskell skriva att area är en funktion av tre parametrar. Det korrekta är dock egentligen att funktionen area är en funktion med en parameter av typen Double som får som resultat av typen Double -> Double -> Double. Funktioner har nämligen alltid en parameter och kan returnera resultat som är funktioner.

Körning: Main> area 3.0 4.0 5.0 Beräkna några trianglars ytor, 6.0 t e den egyptiska triangeln med sidan 3, 4 och 5. Detta sätt att skriva är ganska ovant, och i början kan du se detta som ett sätt att i Haskell applisera area på tre argument. Det korrekta är dock egentligen att att funktionen area appliseras på ett argument, i vårt fall 3.0, och att resultatet blir en funktion av typen Double -> Double -> Double. Denna nya anonyma funktion kan i sin tur appliseras på en nytt argument av typen Double, i vårt fall 4.0 och vi får ett resultat av typen Double -> Double. Denna nya anonyma funktion kan i sin tur appliseras på en nytt argument av typen Double,i vårt fall 5.0 och vi får ett slutresultat av typen Double, i vårt fall 6.0. I stället för where kan man i definitioner använda let.. in. I vårt fall area a b c = let p = (a+b+c) / 2 in sqrt( p*(p-a)*(p-b)*(p-c)) I båda fallen är namnet p som knyts till värdet av uttrycket (a+b+c) / 2 bara användbart i definitonen av area. Java: import java.io.*; public class Heron { static BufferedReader indata = new BufferedReader(new InputStreamReader(System.in)); public static void main(string[] iargs) throws IOEception { System.out.println("Herons formel beräkning av trianglars ytor"); System.out.print("Ge längden för sida a : "); double a = Double.parseDouble(indata.readLine()); System.out.print("Ge längden för sida b : "); double b = Double.parseDouble(indata.readLine()); System.out.print("Ge längden för sida c : "); double c = Double.parseDouble(indata.readLine()); System.out.println("Triangelns yta = " + area(a, b, c)); } public static double area(double ia, double ib, double ic) { double p = (ia + ib +ic) / 2.0; //Herons formula return Math.sqrt(p*(p-ia)*(p-ib)*(p-ic)); } } /* Körresultat Herons formel för beräkning av trianglars ytor Ge längden för sida a : 3.0 Ge längden för sida b : 4.0 Ge längden för sida c : 5.0 Triangelns yta = 6.0 */

Att definiera en funktion: Studera definitionsområdet! Några eempel: en ekvation med ett fall/ flera ekvationer/ en ekvation med flera fall (vakter/case/if)? --------------------------------------------------------------------- Haskell Matte 1.0 3.0-14.0... 4.0 6.0-11.0... f::double->double f = + 3.0 En ekvation klarar alla värden Vi definierar f() = +3 --------------------------------------------------------------------- e j(b) True False True o False True False o b False True ej::bool-> Bool ej True = False Två ekvationer klarar båda värdena False om b = True ej False = True Mönsterpassning Fokker 1.4.3 C&K implicit ej(b) = True (pattern match) Värden, ej namn i V.L. om b = False f() R B B R Sämre: En ekvation med flera fall: med vakter (guards): Fokker 1.4.2 C&K 3.2.2 ej :: Bool -> Bool ej b b = False otherwise = True med if-uttryck (C&k 3.2.1) ej :: Bool -> Bool - ej b = if b then False else True med case-uttryck ej :: Bool -> Bool ej b = case (b) of True -> False False -> True

Haskell Matte --------------------------------------------------------------------- positive() 1.0 True 3.0-14.0 True -6.0 False False positive::double->bool positive En ekvation med vakter True om >= 0 >= 0 = True klarar alla värden positive() = otherwise = False False i övriga fall R B Mönsterpassning med flera ekvtioner fungerar ej. Däremot möjligt men sämre med if eller case. --------------------------------------------------------------------- Rekursion. Om definitionsmängden består av ett ändligt antal värden så kan man helt enkelt skriva en ekvation för varje värde. Det var det vi gjorde när vi definierade ej. Men med ett definitionsområde med oändligt antal värden fungerar det ej, men ofta kan man då använda ett namn i vänsterledet och uttrycka resultatet med ett uttryck som använder detta namn i högerleetd. Ibland blir det ett enda fall i bland flera. I högerledetsuttrycket är är det tillåtet att använda ett anrop till den funktion som vi just definierar. Detta är ofta användbart. Fokker behandlar detta i 1.4.4. (Tillämpningen på listor på sid 13 kan vi ej än), C&K i kapitel 4. Hur kan detta fungera? Jo precis som vanligt! hugs förenklar utrycket som förut tills vi får ett slutresultat som skrivs ut. Det som krävs är att vi för eller senare hamnar i ett icke rekursivt fall, ett basfall.

Ett eempel: Låt os definera power(m, n)= mn Haskell Matte ---------------------------------------------------------------------- 2 3 4 5 0 3 6-14 -6 1 27 729... error "" I, N I power(m, n) m n 1 om n=0 power (m, n) = odefinierat om n<0 m*power(m, n-1) power1 :: Int -> Int -> Int -- vakter för n< 0 Bäst! power1 _ 0 = 1 -- Fokker 1.4.2 power1 m n n<0 = error " second argument till power >= 0" otherwise = m * power1 m (n-1) Eller om vi antar att vi ej skall använda negativa argument (I matte skulle man säga att definitionsmängden är de naturliga talen N. Denna datatyp finns inte färdig i Preluden i Haskell.) power :: Int -> Int -> Int -- rekursiva lösningar för n>0 power _ 0 = 1 -- Fokker 1.4.3 1.4.4 power m n = m * power m (n-1) Enraderskommentarer skrivs med -- i Haskell, // i Java. Flerraderskommentarer omges med {- -} i Haskell, /* */ i Java.

Hur fungerar power? Haskell-system förenklar helt enkelt uttryck (med kontroll av typerna coh använding av definitionerna). Jfr imperativa språk där man för att förstå semantiken måste tänka sig en vonneuman-maskin. power 3 6 blir 3 * power 3 5 blir 3 * (3 * power 3 4) blir 3 * (3 * (3 * power 3 3)) blir 3 * (3 * (3 * (3 * power 3 2))) blir 3 * (3 * (3 * (3 * (3 * power 3 1)))) blir 3 * (3 * (3 * (3 * (3 * (3 * power 3 0))))) blir 3 * (3 * (3 * (3 * (3 * (3 * 1))))) blir 3 * (3 * (3 * (3 * (3 * 3)))) blir 3 * (3 * (3 * (3 * 9))) blir 3 * (3 * (3 * 27)) blir 3 * (3 * 81) blir 3 * 243 blir 729 Minnesåtgång kan bli stor. (En rättfram rekursiv lösning på labbens Fibonacchi-uppgift blir mycket ineffektiv, varför?). En bättre lösning är : power :: Int -> Int -> Int -- accumulerande lösningar med where power _ 0 = 1 power m n n<0 = error " second argument till power >= 0" otherwise = pw m n 0 1 where -- layout Fokker 1.4.5 pw :: Int->Int->Int->Int-> Int pw m n i acc i==n = acc otherwise = pw m n (i+1) (acc*m) power 3 6 blir -- Körning, dvs förenkling eller reduktion pw 3 6 0 1 blir -- Kallas även evaluering, eng evaluation pw 3 6 1 3 blir pw 3 6 2 9 blir pw 3 6 3 27 blir pw 3 6 4 81 blir pw 3 6 5 243 blir pw 3 6 6 729 blir 729 Minneseffektiv. Även i funktionella språk måste man (förstås) tänka ibland. Att denna lösning "inte sväller ut" beror på att det rekursiva anropet av pw ej ingår i något uttryck. Man säger att pw är svansrekursiv."imperativa programmerare" lär sig att skirva "loopar" i dessa fall och att bara tillgripa rekursion när det är svårt att lösa iterativt. (Mer om effektivitet i Fokker kap 5, fast svårläst än så länge) Lösningar med accumulatorer (och, kommer senare, until och foldl men inte foldr) är svansrekursiva.

Egna operatorer. Man kan i Haskell lika lätt definera egna operatorn som funktioner. Om vi vill kunna skriva power 3 6 som 3 ^* 6 (svar 729) kan man göra detta med denna definition: (^*) = power Man kan ocså skriva 3 power 6 Om namn på operator Fokker p 6. ( ) gör funktioner av operatorer Fokker 2.1.1. gör operatorer av funktioner. "Skåpregler" I lösningen ovan definieras hjälpfunktionen pw som en lokal funktion till power med hjälp av where. Man skulle också kunna använda let.. in. I båda fallen kan namnet pw bara användas i definitonen av power, "lokalt scope", lokalt giltighetområde. Vid programutveckling är det ofta enklast att definera power och pw som power :: Int -> Int -> Int -- accumulerande lösningar med where power _ 0 = 1 power m n n<0 = error " second argument till power >= 0" otherwise = pw m n 0 1 pw :: Int->Int->Int->Int-> Int pw m n i acc i==n = acc otherwise = pw m n (i+1) (acc*m) Namnet kan då användas "överallt i modulen", "globalt scope", globalt giltighetområde, och kan användas i provkörningar från hugs. Men i större program anses det ofta som mindre snyggt att låta namn som används lokalt vara globala. Fast Haskell-program blir inte så ofta stora..

Layoutregler. Efter where och let måste "syskon-definitioner" stå rakt under varandra. Detta gäller även "globala" definitioner, eftersom varje fil inleds med en definition module.. where (se labhandleningen). Börjar man längre till vänster på en rad uppfattas detta som man slutat med "syskondefinitioner", börjar man längre till höger som att man använder flera rader för en definition. Detta är mycket praktiskt, men ovant i början. Gör man fel skriver hugs ofts något med att den saknar ;. Se Fokker 1.4.5 C&K 3.6 Att definiera nya (egna) typer. Moduler och ADT. Föresläsningen avslutades med 20 minuter med en snabbkurs i datatypdefiniering, för att komma fram till listor som finns lite av i lab1. Kommer att repetera detta i föreläsning 3. Jag följde delar av kapitel 8 i C& K. De som köpt Fokker kan istället läsa utdraget ur A Gentle Introduction to Haskell 98, sid 13 i labbhäftet. Hit hann vi! Fler eempel mm. På /info/progp02/haskelllectures/f2 finns Date.hs Fallanalys.hs JavaPower.java Power.hs Skatt.hs. Power.hs innehåller totalt 15 olika sätt att definiera power! Jag hoppas att Fokker 1.1 1.3 (dock ej 1.3.5 och 1.3.6), 1.4, 2.1.1 nu till stora delar skall vara lättförståeligt. 2.1.2 och 2.1.3 och 2.14 handlar om ytterligare mekanismer när man definierar operator, bla om prioitets och assocvitet så att man kan undvika parateser i yttryck med många operatorer. C&K Ch 1, Ch3.1 3.2, 3.3 Ch 4.1 bör också vara förståeligt. Märk att funktionsapplikation har högsta prioritet i Haskell! Det vi behandlat på denna föreläsning finns sammanfattat i "att definiera en funktion i Haskell" i labhäftet! Lämpliga övningsuppgifter: i Fokker: 1.4 1.8 1.9 del av 1.10, 2.2. i C&K CH 1.3 alla, Ch 4.5 E 3.