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

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

DD1361 Programmeringsparadigm. Carina Edlund

Föreläsning 8 i programmeringsparadigm. Kommentarer kring schacklabben.

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

Föreläsning 5 i programmeringsparadigm.

Tentamensdag 2002-aug-20 Tentamen i Funktionell Programmering Skrivtid 5 h

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

Enjoy Vattenfallsmodellen i funktionella språk

Enjoy Vattenfallsmodellen i funktionella språk

Föreläsning 4 i programmeringsparadigm.

Kap9. Operatorn.. Hudak 9.4 sid 11. Fermats förmodan, eller Fermats stora sats säger att. xm + ym == zm har heltalslösningar om och endast om m == 2.

Välkomna till DIT012 IPGO. Tyvärr en bug i Google Docs: Sidnummer stämmer inte alltid. Alla anteckningar börjar på sidan 1.

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

Introduktion till Haskell

Nada Tentamensdag 2004 okt 18 Tentamen Programmeringsparadigm Skrivtid 5 h

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

Kungliga Tekniska Högskolan Ämneskod 2D1370 Tentamensdag 2001-maj-31 Tentamen i Funktionell Programmering Skrivtid 4 h

Funktionell programmering DD1361

Men först: Några funktioner ur preluden. Introduktion till programmering. Uppgiften. Variationer av uppgiften. Föreläsning 4

TDDC74 Programmering: Abstraktion och modellering Tentamen, lördag 27 augusti 2016, kl 8 12

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.

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

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

NetBeans 5.5. Avsikt. Projektfönster

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

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

Nada, KTH Tentamensdag maj -24 Tentamen i Funktionell Programmering Skrivtid 5 h

Eclipse. Avsikt. Nu ska ett fönster liknande figuren till höger synas.

Programmering i C++ En manual för kursen Datavetenskaplig introduktionskurs 5p

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

Objektorienterad programmering Föreläsning 2

NetBeans 7. Avsikt. Projektfönster

Inledning. Vad är ett datorprogram, egentligen? Olika språk. Problemlösning och algoritmer. 1DV433 Strukturerad programmering med C Mats Loock

TDDC74 Lab 04 Muterbara strukturer, omgivningar

TDDC74 Programmering: Abstraktion och modellering Datortenta , kl 14-18

Universitetet i Linköping Institutionen för datavetenskap Anders Haraldsson 2

Dagens föreläsning Programmering i Lisp Fö 5

Introduktion till programmering. Standardfunktioner. Vad används datorer till? Standardfunktioner. Föreläsning 2. Prelude. $ ghci...

Sätt att skriva ut binärträd

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 11 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Labb i Datorsystemteknik och programvaruteknik Programmering av kalkylator i Visual Basic

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

Tentamen i TDP004 Objektorienterad Programmering Praktisk del

Föreläsning 8. Hudak kapitel 13. 2D1370 Funktionell programmering v15 torsdag

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

TDDC74 Lab 02 Listor, sammansatta strukturer

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

F4. programmeringsteknik och Matlab

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

Extramaterial till Matematik Y

Föreläsning 3. Programmering, C och programmeringsmiljö

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

Variabler och konstanter

Tentamen i TDP004 Objektorienterad Programmering Praktisk del

Laboration 1 Introduktion till Visual Basic 6.0

Objektorienterad Programmering (TDDC77)

Datorlära 6. Arbeta med strängar Inmatning med tangentbordet Bygga ett program med inmatning, funktioner, osv

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

Lambdas. (och fler design patterns) Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2017

Objektorienterad programmering i Java I. Uppgifter: 2 Beräknad tid: 5-8 timmar (OBS! Endast ett labbtillfälle) Att läsa: kapitel 5 6

Tentamen i TDP004 Objektorienterad Programmering Praktisk del

Instruktioner - Datortentamen TDDD73 Funktionell och imperativ programmering i Python TDDE24 Funktionell och imperativ programmering del 2

Laboration: Grunderna i MATLAB

TDDC74 Programmering: Abstraktion och modellering Datortenta , kl 08-12

Grafiska användargränssnitt i Java

729G04 Programmering och diskret matematik. Python 2: Villkorssatser, sanningsvärden och logiska operatorer

MATLAB. Python. Det finns flera andra program som liknar MATLAB. Sage, Octave, Maple och...

Introduktion till programmering. Programspråk och paradigmer

Användarhandledning Version 1.2

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

TUTORIAL: KLASSER & OBJEKT

729G75: Programmering och algoritmiskt tänkande. Tema 1. Föreläsning 1 Jody Foo

Reguljära uttryck. Reguljära uttryck. Nu kommer en siffra78 och en till SIFFRA(78) men utan 7kstuga SIFFRA(89)

Paneler - VCPXX.2. Programmeringsmanual för VCP-paneler. Revision 2

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

Klassdeklaration. Metoddeklaration. Parameteröverföring

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

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

Del : Paradigmer allmänt.

Introduktion till Matlab

Del : Paradigmer allmänt.

Föreläsning 4: Poster

Program. Kapitel make Program Interpreterande och kompilerande program

Grundkurs i programmering - intro

Uppgift 1 ( Betyg 3 uppgift )

Lab5 för prgmedcl04 Grafik

Java: Utvecklingsverktyg, datatyper, kontrollstrukturer

TDDC74 Programmering: Abstraktion och modellering Datortenta , kl 14-18

OOP Objekt-orienterad programmering

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

Introduktion till programmering och Python Grundkurs i programmering med Python

Emacs. Eric Elfving Institutionen för datavetenskap (IDA) 22 augusti 2016

TDDC74 Programmering: Abstraktion och modellering Tentamen, onsdag 19 oktober 2016, kl 14 18

Grafiska användargränssnitt i Java

TENTAMEN I PROGRAMMERING. På tentamen ges graderade betyg:. 3:a 24 poäng, 4:a 36 poäng och 5:a 48 poäng

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

JAVA Mer om klasser och objektorientering

Använda Python Laboration 1 GruDat, DD1344

4.4 Swing ett interaktivt grafiskt gränssnitt

Föreläsning 3. Programmering, C och programmeringsmiljö

Transkript:

Föreläsning 5 i programmeringsparadigm. Tips kring programmering i Haskell och kring labbarna. Att arbeta med två fönster. Hugs är ju en tolk (interpreter) vilket har stora fördelar vid programutveckling. Man kan ju efter en inledande inladdning till Hugs med :l fortsätta med att göra :r när man gör någon ändring i filen med Haskellkod (spara först!). I Hugs kan man sedan skriva olika uttryck och göra små experiment med sina definierade funktioner och se vad funktionerna får för resultat med olika (enkla) argument. För att kolla en funktions typ kan man helt enkelt skriva funktionsnamnet som ett uttryck (en funktion är ju ett värde, och ett värde är det enklaste formen av uttryck): Prelude> length ERROR - Cannot find "show" function for: *** Expression : length *** Of type : [a] -> Int Värdet skrivs inte ut då funktioner inte ingår i typklassen Show, varför någon funktionen show inte finns för funktionsvärden. Lite elegantare är kanske att använda :t (eller :type ) : Prelude> :t length length :: [a] -> Int Att själv skriva typer: Jag rekommenderar att när man skall skriva t ex en ny funktion först tänka ut typen och skriva in den i Haskell-texten, trots att det i regel egentligen inte behövs då Haskell själv härleder typen. Sedan definierar man funktionen / värdet. Protesterar Haskell, t ex om är typen för generell eller om man får något annat typfel, kan man kommentera bort typuttrycket (med enraderskommentar : --, OBS mellanslag efter -- ) och försöka igen. Går det bra kollar man vad Haskell föreslår för typ. Sedan tänker man. Observera: I definitioner med flera ekvationer att Haskell bestämmer sig för typen i första ekvationen om man inte typar själv. Hittar hugs en annan typ i andra ekvationer blir det fel. Typiskt är att man stirrar på ekvationen för det rekursiva fallet, och inte kan finna något fel, pga att man skrivit basfallet först med något trivialt fel. Flerraders-kommentarer skivs med {- -} Krånglig funktion: Definiera en hjälpfunktion!

Om vikten av att definiera funktionerna för hela definitionsområdet: Hugs kollar inte att man definierat en funktion så att alla tänkbara argument "matchar" någon ekvation. Till exempel : f :: Int -> Int Körning: Main> f 14 f 14 = 2 2 Bättre definiton: Main> f 3 Program error: {f 3} f :: Int -> Int f 14 = 2 f i = error ("f " ++ show i ++ " odefinierat") -- fånig funktion Det är ofta bra att som sista ekvation skriva ett "skön-fall", default-fall, t ex när man håller på med legalmove för ADT Chessman: legalmove =...... legalmove = error "Inte implementerat än i legalmove" När man tycker man är klar kan man byta texten till "Inträffar aldrig i legalmove". Inträffar det i alla fall har man tänkt fel. När man t ex skriver chessquaretographics:: Square -> Chessman -> [Graphic] i steg tre är det viktigt att komma ihåg NoChessman. Hur skriver man en lista med ett enda element (kan vara basfall ibland)? Det finns två sätt: [1] eller 1 :[] är en [Int] med ett enda element med värdet 1. Båda sätten [x] eller (bättre tycker jag) (x :[]) fungerar också i möster ("patterns"). Funktionen concat i steg 6. I steg 6 får man lätt typen[[graphics]] (64 element i listan där elementen består av listor med bilden av en ruta och ibland också bilden av en schackpjäs). I stället vill man ha [Graphics]. Att "platta till" listan gör man med en funktion: concat :: [[a]] -> [a] concat [] = [] concat (x:xs) = x ++ concat xs concat finns förstås färdig i Prelude.

Innehållet i en ADT. Ex i steg 6. En förfrågan : Jag och min labbkompis håller på och kämpar med schacket och har kommit till steg 6, d.v.s vi håller på och implementerar funktionen chesstographics() och har stött på lite patrull. Frågan är hur man fiskar ur (Square, Chessman)-paren från Chess-typen Chess [(Square, Chessman)]? Vi har satsat på att, precis som du tipsar om i kompendiet, att mappa listan i Chess mot chessquaretographics() funktionen via en hjälpfunktion. Problemet är att vi lyckas inte få typerna att matcha. Detta är vår ansats till lösning, som vi tycker ligger närmast till hands: ----------------------------------------------------------- -- Creates a Graphic list for the chessboard. chesstographics :: Chess -> [Graphic] chesstographics chess = map helper chess helper :: (Square, Chessman) -> [Graphic] helper (sq, cman) = chessquaretographics sq cman ----------------------------------------------------------- Använd mönsterpassning (pattern matchning)! Lösning: chesstographics :: Chess -> [Graphic] chesstographics (Chess squarechessmans) = map helper squarechessmans Kommentar : I de flesta språk "plockar man sönder en ADT" med selektorer (motsatsen till konstruerare) sådana funktioner kan man skriva i Haskell också förstås. För den inbyggda typen listor finns head :: [a] -> a tail:: [a] -> [a] och för par finns fst :: (a,b) -> a snd : (a,b) -> b Det är dock enklare att använda mönsterpassning (pattern match), t ex (för listor [], (x:xs), för par(a,b) ). Detta gör vana Haskell-programmerare alltid i den modul som definierar ADT-en. Vill man använda mönsterpassningi andra moduler (och det vill man nog ofta), måste man exportera konstruerarna för den konkreta datatypen. Datatypen är då inte längre abstrakt tyvärr. Konstruerarna definieras ju så här: data <Nytyp> = <Konstuerare>.. <Konstuerare> Tre sätt att exportera konstruerarna: module <NytypDT> where -- allt exporteras, enklast module <NytypDT> (<här räknar man upp det somskall exporteras inkl <Nytyp> och konstuerare> ) where module <NytypDT> (<här räknar man upp det som skall exporteras inkl <Nytyp> (..)) where

"uncurring" mm. Ex helper ovan steg 6. Fokker 3.3.5 Funktionen helper (sq, cman) = chessquaretographics sq cman ovan behövs för att chessquaretographics har typen chessquaretographics :: Square- > Chessman -> [Graphic] men skulle kunna funktionen direkt som argument till map om den hade typen chessquaretographics:: (Square, Chessman) -> [Graphic] Finns det andra lösningar än att använda en hjälpfunktion? 1. Skriva om chessquaretographics.(tar mindre än en minut.) 2. Vi kan definera helper = \(sq, cman) -> chessquaretographics sq cman Lamda-uttrycket kan då "smackas in direkt" i map-uttrycket (Tar ca 20 sekunder att göra.) chesstographics (Chess squarechessmans) = map ( \(sq, cman) -> chessquaretographics sq cman) squarechessmans Med denna teknik kan man klara sig om man inte använder partiellt applicerade funktioner, nåt som jag ju brukar propagera för. 3. Det skulle vara bra att slippa göra sådana här förvandlingar varje gång problemet dyker upp. Hur löser man det? Med funktioner förståss: Två användbara funktioner (finns förstås i Prelude) (överkurs i fjol) : curry :: ((a,b) -> c) -> a -> b -> c curry f x y = f (x, y) uncurry:: (a -> b -> c) -> (a,b) -> c uncurry f (x,y) = f x y Vi kan nu göra sånt som Prelude> uncurry (+) (3, 4) 7 -- Om du tvilar på att det uncurry kan vara så enkel, förenkla detta uttryck! I vårt fall : (tar 5 sekunder om man känner till att uncurry finns i Prelude) chesstographics (Chess squarechessmans) = map (uncurry chessquaretographics) squarechessmans

Steg 3, 4, 5, 6 och 7 i Schacklabben. Kommentar kring motsvarande sidor i labhäftet. Repetition: Övning 3.10 i Fokker. 3.10. Write a function stringint that turns a string into the corresponding integer. For example stringint "123" gives the value 123 Finns på./info/progp03/haskelllectures/fokker.hs Inbyggd funktion : Prelude> read "123" ERROR - Unresolved overloading *** Type : Read a => a *** Expression : read "123" -- "overloaded", "överlagrade funktioner : -- read :: Read a => String -> a -- show :: Show a => a -> String Prelude> (read "123") :: Int -- typning av uttryck, nytt, 123 -- sällsynt Prelude> Bra hjälpfunktion, visade sig finnas i Prelude: digittoint :: Char -> Int --fanns i Prelude! digittoint s isdigit s = fromenum s - fromenum 0 otherwise = error (s : " not digit") Skriv typen: stringtoint :: String -> Int Olika lösningar: stringtoint = read -- enklast stringtoint [] = 0 --standardsättet, ganska komplext stringtoint (s:ss) = digittoint s *10 ^ length ss + stringtoint ss stringtoint siffror = sti (reverse siffror) -- fiffigt vänd på sträng where sti [] = 0 sti (s:ss) = digittoint s + 10 * sti ss stringtoint siffror = sti siffror 0 -- accumulering where sti [] acc = acc sti (s:ss) acc = sti ss (digittoint s + 10*acc) stringtoint s = -- med until snd (until (\(s, _ ) -> s == []) (\(s:ss, num) -> (ss, 10*num + digittoint s)) (s, 0 )) Vilka lösningar är svansrekursiva?

Interaktiva program. Se också labb-häftet 38 <= sid <=48. Inför steg 8 och 9. Hugs tillåter att vi skriver in ett uttryck, Hugs förenklar uttrycket och skriver dess värde. Detta gör den för alla uttryck vars reultattyp är med i typklassen Show (därför är det bra att skriva deriving Show, när man definierar egna typer. Vad en typklass är kommer senare att behandlas). När vi kört ett "program" med hugs som vi skrivit har vi ju i regel skrivit ett uttryck som varit ett funktionsanrop med argument. Argumenten har varit våra "indata", hugs svar (funktionens resultat) våra "utdata". Men hur skriver man i Haskell program där indata skall ges efter det att en del utdata redan har skrivits på skärmen? T ex ett program som ger denna körning (inmatning kursiverat i denna text): Main> main Vad heter du? Leif Goddag Leif! Main> Kunde det kanske skrivas så här : main :: String main = "Vad heter du? " ++ "Goddag " ++ getline ++ "!") där getline ::?? -> String vore någon slags inmatningsfunktion? Nej! Detta stider mot alla grundregler för funktionell programmering! "Programmet" (dvs funktionen main) har olika betydelser vid olika tillfällen. Vad som skrivs beror på inmatningen, en "sidoeffekt". Dessutom: När skall inmatningen ske? Det framgår ju inte alls av "programmet" ovan att vi vill ha inmatningen efter det Vad heter du? skrivits men före Goddag skrivits, men den inmatade stängen skall komma efter Goddag. Hittills har vi ju hela tiden kunnat förklara Haskells semantik (dvs vad ett Haskell-uttrryck betyder, dvs vad som händer vid körningen) med att Haskell helt enkelt förenklar uttrycket med samma regler som i matematiken. Vi har varit lyckligt förskonade med fråger som "efter","före" och "när". Men hur skrivs program som det ovanstående? Detta problem löses för tidiga funktionella språk genom att man "fuskade" och lät språken ha en litet komprometterande imperativt tillägg, som man motvilligt lärde ut på slutet och använde så litet som möjligt. Kring 1990 insåg man att något som kallas monader kunde lösa problemet. Haskell använder monader av typ IO a för mer sofistikerad in och utmatning. I denna kurs hinner vi inte lära ut monader ordentligt, utan jag ger i labhäftet generella funktioner som sköter in och utmatning och använder Haskell funktioner av vanlig sort för att programmera det som är specifikt för varje tillämpning.

I boken M.M.T.Chakravarty, G. C. Keller : An Introduction to Computing, kapitel 7 finns en utmärkt beskrivning av IO (Input and Output) i Haskell. Det följande är citerat från den boken: The situation found in the case of a text editor, where the main purpose of a program is interaction, but internally many computations are executed, is typical. In general, we can regard programs to be composed of an inner computational kernel and an outer interaction shell... I denna kurs har jag skrivit 3 st generella funktioner för skalet. Interaction ( -> IO a) Computational Kernel ("Vanlig Haskell") Shell Jag har gjort skalet så "tunt" men generellt som möjligt. showgraphics kan rita bilder (för steg 4). makeinteractiveprogram kan användas för att skriva program med textinmatning och textutmatning "inflätade" i varandra. makegraphicinteract (för steg 8 och 9). kan användas för att skriva program med inmatning med "klickningar" på bild och bildritning "inflätade" i varandra. Although good programming style requires a clean separation between the computation and the interaction components, most programming languages do not make a clear distinction between these two kind of programming code.... Haskell - being a very clean languges - does. Överkurs (C&K kapitel 7 kan läsas som en intoduktion till programmering i IO-monaden) : Monader är en ADT med bland annat operatorerna >> och >>=. Så här skriver man main: main :: IO () main = putstr "Vad heter du? " >> getline >>= (\ input -> putstr ("Goddag " ++ input ++ "!")) Detta uttryck är korrekt funktionell programmering. För att imperativa programmerare skall känna igen sig kan monad-uttrycket också skrivas med en alternativ syntax : main = do putstr "Vad heter du? " input <- getline putstr ("Goddag " ++ input ++ "!") Programmering med do-syntax i IO-monaden påminner mycket om klassisk imperativ programmering. Vad som skiljer och att det ändå är korrekt funktionell programmering, se litteraturen.

Om programmet makeinteractiveprogram, se labbhäftet. Interaktivt program med makeinteractiveprogram: Samspelet mellan makeinteractivprogram och modellen i "vankig" Haskell: Interaction main = makeinteractiveprogram.. f, startstatus, promt Ev hjälpfunktioner Computational Kernel ("Vanlig Haskell") Shell -> IO a Om programmet Till21, sid 42,43 i Haskell-labb-häftet: Kör programmen i /info/progp02/haskell, t ex Till21.hs, Till21Graf.hs Om programmet makegraphicinteractiv, se labbhäftet. Om programmet Till21Graf sid 45, 46 i Haskell-labb-häftet: Funktionen f i Till21Graf fungerar nästan likadant som i Till21, men tripplarna ersätts av par eftersom avslutning av programmet styrs med klick i stängningsrutan. f returnerar ett par med typen ((Int, Bool),[Graphic]) för att passa till makegraficinteract.

Steg 8 och 9 i Schacklabben. Vi använder förstås makegraphicinteract. Interaction main = makegraphicinteract.. changechess, startstatus,"schack" i modell Square Chessman Chess Computational vy ChessGraphic Kernel ("Vanlig Haskell") Shell -> IO a styrning (control) PlayChess Repetition av olika definitioner i Haskell: Vi kan nu definiera nya namn.. på ( om hur typklasser definieras i föreläsning 7): värden: namn på funktioner (liten bokstav)......=.. eller (liten bokstav).. = <lamdauttryck> namn på konstanter (liten bokstav).. =.. namn på konstruerarfunktioner (Stor bokstav ) data... =........ namn på konstruerakonstanter (Stor bokstav ) data... =.. Används i uttryck (Vita värden) typer: namn på typer (Stor bokstav ) data.. =...... namn på typsynonymer (Stor bokstav ) type.. =... namn på typvariabler (liten bokstav) (ingen def.!) Används efter :: (Röda värden) typklasser: namn på typklasser (Stor bokstav ) class.. a where Används före => moduler: namn på moduler (Stor bokstav ) module.. where Används efter import

fold. (Föreläsning 6) Man har ofta anledning att "vika ihop" listor, dvs slå samman alla elementen med hjälp av en binär operator/funktion. T ex om vi skall summera elementen i en lista: [1, 14, 5] kan vi se detta som om vi skall stoppa in ett + efter elementen och en nolla längst åt höger ( " ~ på alla ställen där det står ett,") (1 + (14 + (5 + 0))) Detta har vi gjort med denna definition sum :: Num a => [a] -> a sum [] = 0 sum (x:xs) = x + sum xs Detta kan vi generalisera för godtycklig binär operator/funktion, godtyckligt värde "längst till höger" : foldr :: (a -> b -> b) -> b -> [a] -> b foldr f z [] = z foldr f z (x:xs) = f x (foldr f z xs) Vi skulle kunna kan nu definiera sum = foldr (+) 0 T e x blir sum [1, 14, 5] blir foldr (+) 0 [1, 14, 5] blir foldr (+) 0 (1:14:5:[]) blir (vi stoppar in + infixt ) (1 + foldr (+) 0 (14:5:[])) blir (1 + (14 + foldr (+) 0 (5:[])) blir (1 + (14 + (5 + foldr (+) 0 []))) blir (1 + (14 + (5 + 0))) blir (1 + (14 + 5)) blir (1 + 19) blir 20 r i foldr står för right, "paranteserna till höger". foldl "paranteserna till vänster left": foldl f z [] = z foldl f z (x:xs) = foldl f (f z x) xs sum är i preluden definierad med en icke-lat (kommer i föreläsning 7) variant av foldl (varför?) : sum = foldl (+) 0

Reduktion: sum [1, 14, 5] blir foldl (+) 0 [1, 14, 5] blir foldl (+) 0 (1:14:5:[]) blir (vi stoppar in + infixt ) foldl (+) (0+1) (14:5:[]) blir foldl (+) (1+14) (5:[]) blir foldl (+) (15+5) [] blir 20 concat är i Prelude definierad med foldr : concat = foldr (++) [] Haskell och andra språk. Kompilering och interpretering. (föreläsning 7) Haskell hade troligen varit ett mer använt språk om det tidigt funnits standard för samverkan med kod skrivit i andra språk. Standard för detta börjar komma först nu. Man kan kanske tycka att språket är så bra att man inte behöver beblanda sig med underlägsna imperativa språk, men de finns personer som anser en sådan inställning orealistisk. Eftersom kod skrivna i andra språk ofta har sidoeffekter bör Haskell betrakta importerade funktioner i skrivna i "främmande" språk som funktioner med resultat av typ IO (). Hugs är en interpretator, dvs Haskell texten läses på nytt varje gång programmet används. Haskell kan även kompileras, varvid texten översätts av kompilatorn och det är översättningen som används vid varje körning. Den mest använda kompilatorn heter ghc.. Överkurs: Så här får man tillgång till ghc:..>module add ghc Man kan nu använda ghc interaktivt på detta sätt (mycket likt som man använder hugs, men man kan inte använda SOEGraphics):..>ghci Med ghci kan blanda ett interaktivt körsätt av någon Haskell-module med färdigkompilerad kod för importerade moduler. Vill man göra rena kompileringar skrivar man..>ghc...... Kompilatorn genererar C-kod, som därefter automatiskt kompileras med C-kompilatorn gcc och laddas med ld. Jag har lärt mig att även blanda in kod som skrivits med C, jag kanske skriver mer om detta i kommande föreläsningshäften.

Haskell och Tcl/Tk. Överkurs. (Föreläsning 7) Tcl/Tk är, tror jag, C-världens sätt att göra GUI program på samma sätt som man i Java kan göra program med knappar (Buttons) och andra grafiska komponenter. I Bremen har man gjord ett paket HTk i Haskell som använder Tcl/Tk. Jag har lyckats kombinera detta med vår schackmodell från labbarna: Interaction main i PlayChessTcl.. changechess i PlayChessTcl modell Square Chess Chessman vy styrning Computational Kernel ("Vanlig Haskell") Shell -> IO a PlayChessTcl innehåller kod för hela vyn och den interaktiva delen av styrningen. Om du har lust att pröva min PlayChessTcl tillsammans med dina Sqaure, Chess och Chessman så finns programmet på /info/progp03/playchesstcl.hs. Man måste ha kompletterat Chess på det sätt som beskrivs i steg 8 och 9, namnen på vissa fuktioner måste ju stämma osv. Kompilering och laddning tar lång tid, den körbara koden blir 8 MByte, det har varit mycket krångel innan vi fick Htk att funka, så lycka till... Däremot : Den rena Haskell-delen (modellen från SOEGraphics- versionen) var bara att smacka in, det funkade direkt (förståss!?). Hur man kompilerar och laddar står i början av filen Du kan (förhoppningsvis) även köra mitt program som...>setenv LD_LIBRARY_PATH ${LD_LIBRARY_PATH}:/pkg/gnu-libs/1.1/lib...>PlayChessTcl