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

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

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

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

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

Funktionell programmering DD1361

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.

Programmering A. Johan Eliasson

Föreläsning 4 i programmeringsparadigm.

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

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

Klassdeklaration. Metoddeklaration. Parameteröverföring

TDIU01 - Programmering i C++, grundkurs

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

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

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

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

Undervisning. Examination

Objektorienterad Programmering (TDDC77)

Del : Paradigmer allmänt.

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

TDDC77 Objektorienterad Programmering

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

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

(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

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

Introduktion till Haskell

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

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

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

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

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

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

F4. programmeringsteknik och Matlab

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

Programmeringsteknik med C och Matlab

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

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

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

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

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.

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

Övning2. Variabler. Data typer

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

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

Föreläsning 3-4 Innehåll

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

Objektorienterad Programmering (TDDC77)

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

F2 Datatyper och variabler. ID1004 Objektorienterad programmering Fredrik Kilander

Tentamen OOP

Undervisning. Examination

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

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

Föreläsning REPETITION & EXTENTA

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

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

Användarhandledning Version 1.2

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

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

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

TENTAMEN PROGRAMMERINGSMETODIK MOMENT 2 - JAVA, 4P

Föreläsning 2 Programmeringsteknik och C DD1316

TDIU01 - Programmering i C++, grundkurs

Villkor och tester. Utförande satser bygger upp metoderna, man brukar finindela detta i: sekvenser. Ett program består i princip av: selektioner (val)

Rekursion och induktion för algoritmkonstruktion

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

Grundläggande datalogi - Övning 1

Nada KTH 2004 jan 12 Tentamen Programmeringsparadigm 2D1350 Skrivtid 5 h 8-13

Nada Tentamensdag 2004 okt 18 Tentamen Programmeringsparadigm Skrivtid 5 h

Alla datorprogram har en sak gemensam; alla processerar indata för att producera något slags resultat, utdata.

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

Dagens föreläsning. Repetition. Repetition - Programmering i C. Repetition - Vad C består av. Repetition Ett första C-program

TDIU01 - Programmering i C++, grundkurs

Classes och Interfaces, Objects och References, Initialization

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

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

Att skriva till och läsa från terminalfönstret

DIAGNOSTISKT PROV. Tid. Hjälpmedel. Antaganden. Rättning. Övrigt. Diagnostiskt Prov. Klockan Inga

Föreläsning 2 Objektorienterad programmering DD1332. Typomvandling

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

Imperativ programmering. Föreläsning 2

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

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

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?

TDIU01 - Programmering i C++, grundkurs

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

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 2 Programmeringsteknik DD1310. Programmering. Programspråk

F5 Selektion och iteration. ID1004 Objektorienterad programmering Fredrik Kilander

Föreläsning 1 & 2 INTRODUKTION

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ög abstraktionsnivå => kraftfulla språk T e alla namn är referenser, ingen (eplicit) "pekarprogrammering" Haskell logiskt bra typsystem => kraftfulla språk => Hittar många slarvfel Haskell Typklasser => Överlagrade funktioner Högre ordningens funktioner, def med ekvationer => kraftfulla språk Funktioner kan var resultat till funktioner Funktioner kan var argument till funktioner Lat evaluering, ger oändliga datastrukturer Resultat räknas ut fört när de behövs, effektivt Haskell Moduler => Modern programutveckling ADT Jämför Hutton 1.3 Hutton nämner också listomfattning (eng list comprehnsion), och monadprogrammering, som vi skall lära oss, och möjligheten att bevisa att program är korrekta.

Historik, geografi Hutton1.4 Fokker 1.1 C&K 1.1 (Chakravarty & Keller) När man vill tänka imperativt (simulering)? Gräns mellan paradigmer Bra begrepp? 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.. 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"). I funktionella språk skriver man uttryck, och man kan få datorn att beräkna uttryck. Uttrycken kan innehålla operatorer och funktioner från "Prelude". Värdena i uttrycket är "indata", hugs svar "utdata". Snart är det dags att skriva (definiera) egna funktioner, vilket är "att programmera" i Haskell. Man kan även definiera egna värden tillhörande olika typer och gruppera typer. Det är i stort sett altt, det räcker! Det finns inga "satser" (kommandon), inga programmeringsvariabler, mm, mm.. Behövs ej! För att få godkänt på den här kursen: Gör..>res checkin progp05

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 (hutton kap 3): 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(hutton kap 4): 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 i ett skript (i emacsfönstret) som man sedan kan ladda in och använda i hugs. Egna funktioner får namn i en funktionsdefinition. Funktioner är ett slags värden i Haskell, känns ovant i början. 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).T e kan det i ett skript stå nysida = True eller pi = 3.14 eller f = 3.0 *. 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. Hutton gör så i kapitel < 7. Det korrekta är dock egentligen (Hutton 3.6, kapitel 7) 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 Hutton 4.3 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): Hutton 4.3 Fokker 1.4.2 C&K 3.2.2 ej :: Bool -> Bool ej b b = False otherwise = True med if-uttryck (Hutton 4.2, 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. hutton väntar med detta till kapitel 6. 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. 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. (Hutton 2.4.3) 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 ;. Jag hoppas att mycket av Huttons inledande kapitel ungefär (1 <= kapitel <= 4, delar av 6) ska vara begripligt. Vi har dock ännu inte tagit upp t e 3.7, 3.84.6, 4.5, 4.4.1, 4.42, 4.4.3 (4.4.3 tänker jag strunta i), kapitel 5. Efter det vi studerat hur man gör typer ska vi komplettera med överhoppat material. Märk att funktionsapplikation har högsta prioritet i Haskell! Lämpliga övningsuppgifter:i Hutton 1.7.1,1.7.3, 2.6.1, 2.6.3 Det vi behandlat på denna föreläsning finns sammanfattat i "att definiera en funktion i Haskell" i labhäftet! Att definiera nya (egna) typer. Moduler och ADT. Hutton hade i juni ännu intge skrivit sitt typkapitel, så istället läser vi utdraget ur A Gentle Introduction to Haskell 98, som finns i slutet av häfte som börjar med uttdraget från Hutton. 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!