07 Haskell

Werbung
K07 Haskell 1.  Grundlegende Eigenscha2en 2.  GHCi und GHC 3.  Typsystem teilweise basiert auf Folien von Graham HuBon und Philip Wadler thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 2 Haskell Literatur n 
M. Block, A. Neumann: Haskell-­‐Intensivkurs: Ein kompakter Eins5eg in die funk5onale Programmierung. Springer, 2011. ISBN: 978-­‐3-­‐642-­‐04717-­‐6 Frei/online verfügbar: n 
n 
B. O'Sullivan, D. Stewart, J. Goerzen: Real World Haskell. First EdiLon. O‘Reilly, 2008. ISBN: 978-­‐0-­‐596-­‐51498-­‐3
hBp://book.realworldhaskell.org/ M. Lipovača: Learn You a Haskell for Great Good! No Starch Press, 2011. ISBN: 978-­‐1-­‐59327-­‐283-­‐8 hBp://learnyouahaskell.com/ thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 1 3 Historischer Hintergrund n 
Ursprung: n 
n 
n 
n 
λ-­‐Kalkül (A. CHURCH und S. KLEENE – 1930er Jahre) Currying* (HASKELL BROOKS CURRY – 1950er Jahre) Lisp als erste Programmiersprache mit funkLonalen Eigenscha2en (J. MCCARTHY 1958) Haskell 1.0 – (P. HUDAK, J. HUGHES, SIMON P. JONES, P. WADLER 1990); aktuelle Version: Haskell 2010 *Zuvor schon von G. FREGE und M. SCHÖNFINKEL beschrieben. thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 4 Ist FP relevant? n 
Viele Konzepte der FP finden Eingang in den „Alltag“ der So2wareentwicklung bzw. in die Weiterentwicklung konvenLoneller Sprachen: xmonad PUGS PERL 6 Compiler Projekte, die in Haskell geschrieben sind (Auswahl) Google MapReduce Übersicht: hBp://www.haskell.org/haskellwiki/Haskell_in_industry thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 2 5 Warum gerade Haskell und nicht ... ... Erlang, F#, Lisp, ML, O‘Caml, Scheme, Scala, ... n 
n 
Rein funkLonale Sprache – „purely funcLonal“ Unter den funkLonalen Programmiersprachen sehr populär n 
n 
n 
Compiler als auch interakLve Interpreter verfügbar (z.B. Glasgow Haskell Compiler ghc und ghci) n 
n 
n 
Grosse Menge an Bibliotheken Nicht nur Gegenstand der Forschung, sondern industriell eingesetzt (man sollte es nicht als eine „akademische Spielwiese“ auffassen) Gute bis sehr gute Laufzeitperformance wenn kompiliert Tools für Entwickler (IDEs, Debugger, Build, Profiler) Entworfen durch ein Komitee thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 6 Was ist FunkLonale Programmierung? Allgemein zusammengefasst: n  ProgrammiersLl (Paradigma) dessen grundlegende Methode die Anwendung von Funk2onen auf deren Argumente ist: Ein Programm ist formuliert als eine (möglicherweise aus vielen UnterfunkLonen zusammengesetzte) FunkLon im math. Sinn, dessen Ausführung der Auswertung dieser FunkLon entspricht. n 
Eine funkLonale Programmiersprache unterstützt / fördert / erzwingt diesen ProgrammiersLl. thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 3 7 Gegenüberstellung n 
Gesucht: Summiere die Zahlen 1...10! Funktion Argument In C++: In Haskell: int sum = 0; for (int i=1; i<=10; i++) { sum += i; } sum [1..10] sum :: Num a => [a] -­‐> a sum [] = 0 sum [x] = x sum (x:xs) = x + sum [xs] ImperaLv: Iteriere über die Zahlen 1 bis 10 und addiere die aktuelle Zahl zur Gesamtsumme. ApplikaLv: Wende die FunkLon sum auf die Liste der Zahlen 1 bis 10 an, wobei sum die FunkLon ist, die die Summe einer Liste von Zahlen berechnet. thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 8 FunkLonsanwendung und -­‐KomposiLon graustufen :: Bild -­‐> Bild springer :: Bild graustufen graustufen springer spiegeln :: Bild -­‐> Bild neben :: Bild -­‐> Bild -­‐> Bild neben (spiegeln springer) (graustufen springer) graustufen neben spiegeln duplizieren thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 4 9 Neue FunkLon aus bestehenden FunkLonen definieren graustufen neben spiegeln duplizieren duplizieren :: Bild -­‐> Bild duplizieren x = neben (spiegeln x) (graustufen x) duplizieren springer thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 10 Haskell: Zurück zur MathemaLk x = x +1
n 
n 
In Haskell ist dies eine rekursive DefiniLon von x. In der MathemaLk ist dies eine nicht lösbare Gleichung. Die Variable x ist fest an einen Wert gebunden; x ist nicht veränderbar (engl. immutable). In imperaLven Sprachen ist dies eine Anweisung um den Zustand (Bereich im Speicher) der mit der Variable x assoziiert ist – eine Zahl in diesem Fall, die irgend etwas repräsenLert, z.B. das Alter einer Person – zu verändern. thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 5 11 Wiederholung: FunkLon X
n 
f
Y
In der MathemaLk ist eine FunkLon f eine Abbildung, die ein Element x einer Menge X eindeuLg (aber nicht notwendiger Weise eineindeuLg) auf ein Element y einer Zielmenge Y abbildet. f : X → Y
n 
n 
n 
Linkstotal, d.h. für alle Elemente von X definiert (falls nicht, dann nennt man f eine parLelle FunkLon). RechtseindeuLg, d.h. für jedes Element x ∊ X gibt es höchstens ein Element in y ∊ Y auf das x abgebildet wird. X als auch Y können Produktmengen sein: X = X1 × ... × Xn,
Y = Y1 × ... × Ym (n ≥ 0, m ≥ 1) wobei Xi, Yj wiederum Mengen sind, × das kartesische Produkt und n die Stelligkeit (engl. arity) von f angibt (z.B. liefert X = A × B × C eine dreistellige FunkLon, wobei die Argumente Elemente aus A, B, C sind). thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 12 Merke n 
n 
Egal wann und egal wo f ausgewertet (oder angewendet) wird, das Ergebnis y ∊ Y ist nur durch den Parameter x ∊ X besLmmt (anhand der Abbildungsvorschri2 die durch f vorgegeben ist) und sonst nichts. Ist f eine FunkLon im mathemaLschen Sinn, dann erzeugt sie keine Seiteneffekte. Der einzige „Effekt“ der Auswertung von f ist die Berechnung des Ergebnis y ∊ Y. n 
Mit anderen Worten: n 
n 
Der Datenfluss – d.h. die Benutzung von Ergebnissen durch nachgeordnete FunkLonen – ist explizit; es gibt keine impliziten Effekte. Es gibt keinen „versteckten“ (impliziten) Zustand der das Ergebnis einer FunkLon beeinflusst. Demzufolge kann auch kein Zustand durch einen FunkLonsaufruf verändert werden. thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 6 13 ReferenLelle Transparenz engl. referenLal transparency/opaqueness n 
n 
n 
Ist e ein Ausdruck im math. funkLonalen Sinn (z.B. g(f(x),y)), dann ist e eindeuLg durch die Argumente (und die AuswertungssemanLk die für e definiert ist) besLmmt; d.h. ... ... gegeben die Argumente, dann kann man e durch sein Ergebnis bzw. einen äquivalenten („leichteren“) Ausdruck e'
ersetzen (subsLtuieren) Diese Eigenscha2 bezeichnet man als referenLelle Transparenz à Formaler mathemaLsch/logischer Beweis der Korrektheit eines Programms (liefert es das was es soll) wird dadurch vereinfacht bzw. überhaupt erst möglich, da keine Seiteneffekte mit einbezogen werden müssen. thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 14 Moment mal, wie kann man dann... n 
... folgende Dinge* in Haskell (bzw. rein funkLonalen Programmiersprachen) realisieren: n 
n 
n 
n 
n 
random() – erzeugt eine Zufallszahl keine Funk2onen im math. Sinn getInput() – liefert ein über die Tastatur eingegebenes Zeichen currentTime() – liefert die aktuelle Uhrzeit/das aktuelle Datum queryGoogleFor(x) – liefert Suchergebnisse für SLchwort x Haskell bedient sich hierfür der Monoide, Morphismen und Funktoren, welche Konzepte aus der Kategorientheorie der MathemaLk sind: n 
Ac2on – monadische FunkLon („unreine“ FunkLon mit Seiteneffekten) Arrow – VerkeBung/KomposiLon von AcLons spezielle Monoide n 
Monad – Struktur aus AcLons; besLmmt wie AkLonen ausgeführt werden. n 
* An dieser Stelle sei absichtlich nicht der Begriff FunkLon (bzw. FunkLonalität) verwendet. thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 7 15 FunkLon höherer Ordnung n 
... ist eine FunkLon bei der ein oder mehrere Argument(e) und/
oder das Ergebnis wiederum eine FunkLon sind. n 
n 
n 
(X → Y ) → Z
FunkLonen, genauso wie Argumente, sind „first-­‐class ciLzens“ Hauptanwendung liegt in der AbstrakLon von mehreren FunkLonen an einem Ort. Beispiele (informell): n 
n 
n 
Eine FunkLon die eine Liste von Zahlen und die Quadrat-­‐FunkLon als Argumente hat, die auf jede Zahl die Quadrat-­‐FunkLon anwendet und die so entstandene Liste der Quadratzahlen zurückgibt. Eine FunkLon die eine Liste von Zahlen und die Maximum-­‐FunkLon als Argumente hat, die sukzessiv die Maximum-­‐FunkLon auf je zwei Zahlen anwendet um dadurch den grössten Wert der Liste zu finden. Für eine differenzierbare FunkLon f, liefere deren erste Ableitung f ' als Ergebnis. thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 16 Bedarfsauswertung engl. lazy evaluaLon, call-­‐by-­‐need n 
ReferenLelle Transparenz ermöglicht Bedarfsauswertung ... n 
n 
n 
n 
... da es keine Rolle spielt ob das Ergebnis einer FunkLon bei jedem Aufruf immer (in aufwändiger Weise) berechnet wird, oder erst dann, wenn das Ergebnis wirklich gebraucht/verwendet wird, d.h. ... ... ein Ausdruck wird dann ausgewertet wenn darauf zugegriffen wird. Defini2on (Strikte FunkLon): Sei f eine Funk5on und e ein nichGerminierender Ausdruck. f ist strikt gdw. f(e) nicht terminiert. Haskel ist nicht strikt. Was nicht benöLgt wird für eine Berechnung, wird niemals ausgewertet werden. Demzufolge sind Ausdrücke deren Auswertung unendlich lang laufen würde, oder die nicht vollständig berechenbar sind (da z.B. fehlerha2), die aber nicht (kompleB) ausgewertet werden müssen, kein Problem. thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 8 17 Bedarfsauswertung n 
(ii) Ermöglicht es unendliche Strukturen zu deklarieren und damit zu arbeiten; z.B.: n  Liste aller posiLven Ganzzahlen: [1..] n  Unendliche Liste von Einsen:
ones = 1 : ones n  Liste aller Quadratzahlen:
squares = map (^2) [1..] Beispiel: n 
head :: [Int] -­‐> Int -­‐-­‐ Funktion welche aus einer head [] = undefined -­‐-­‐ Liste von Integer Zahlen head (x:xs) = x -­‐-­‐ die erste Zahl zurück gibt. head [1..] -­‐-­‐ terminiert und liefert “1” head ones -­‐-­‐ dito head squares -­‐-­‐ dito Nachteil: es ist u.U. schwieriger vorhersagbar, wann bzw. ob eine Ressource tatsächlich benutzt wird (z.B. Netzwerkzugriff erfolgt). thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 18 Weitere wesentliche Eigenscha2en n 
In Haskell (und anderen „rein“ funkLonalen Sprachen) exisLeren keine Kontrollstrukturen wie z.B. Schleifen n 
n 
n 
n 
StaBdessen wird Rekursion benutzt Strenges Typsystem: Alle Typen staLsch zur Compilezeit bekannt, wodurch TypinkompaLbilitäten erkennbar sind. Polymorphes Typsystem: FunkLonen können für eine Klasse verschiedener Typen anwendbar sein. AutomaLsche Speicherverwaltung: keine ZeigermanipulaLon; kein Anfordern und Freigeben von Speicher. thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 9 19 Haskell: Kostproben Das obligatorische Hello World: DateinamenskonvenLon hello.hs module Main where main :: IO() main = putStrLn "Hello, World" Quick Sort ? f :: Ord a => [a] -­‐> [a] f [] = [] f (x:xs) = f ys ++ [x] ++ f zs where ys = [a | a <-­‐ xs, a <= x] zs = [b | b <-­‐ xs, b > x] QS noch kompakter f :: Ord a => [a] -­‐> [a] f [] = [] f (x:xs) = f [a | a<-­‐xs, a<=x] ++ [x] ++ f [b | b<-­‐xs, b>x] thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 20 Schlüsselwörter in Haskell Schlüsselwörter in Haskell as case of default deriving deriving instance do class data data family forall foreign hiding import data instance if then else instance let in infix infixl infixr mdo module newtype proc qualified rec type type family type instance where Nur in besLmmten Kontext reserviert. Kann andernorts als FunkLons-­‐ bzw. Variablen-­‐Name benutzt werden. thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 10 Haskell K07 1.  Grundlegende Eigenscha2en 2.  GHCi und GHC 3.  Typsystem thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 22 GHCi – InterakLver Haskell Interpreter n 
n 
Glasgow Haskell Compiler (GHC) kann als die Referenzimple-­‐
menLerung von Haskell betrachtet werden. Wird auch am häufigsten benutzt. GHCi ist ein interakLver Interpreter zum Testen (Scrapbook) n 
Starten durch ghci thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 11 23 GHCi – einfache Ausdrücke auswerten n 
> ist der Eingabeprompt; zeigt an, dass GHCi bereit zum Auswerten von Ausdrücken ist. thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 24 Prelude – die Standardbibliothek n 
Prelude.hs ist eine Bibliothek (genauer gesagt ein module) welche per Default zur Verfügung steht. n 
Bietet zahlreiche, grundlegende FunkLonen und Datentypen an > compare 2 3 LT
-­‐-­‐ Relation zweier Elemente aus Menge -­‐-­‐ mit definierter Ordnung (LT, GT, EQ) > head [1,2,3,4,5]
1
-­‐-­‐ erstes Element einer Liste -­‐-­‐ analog liefert tail die Restliste > [1,2,3,4,5] !! 2 -­‐-­‐ n-­‐tes Element einer Liste 3 > take 3 [1,2,3,4,5] -­‐-­‐ ersten n Elemente einer Liste [1,2,3] thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 12 25 Prelude – weitere Beispiele > drop 3 [1,2,3,4,5] -­‐-­‐ Restliste ohne die ersten n Elemente [4,5] > length [1,2,3,4,5] -­‐-­‐ Länge der Liste (Anzahl Elemente) 5 > product [1,2,3,4,5] -­‐-­‐ Produkt aller Listenelemente 120 > [1,2,3] ++ [4,5] -­‐-­‐ Konkatenation zweier Listen [1,2,3,4,5] > reverse [1,2,3,4,5] -­‐-­‐ umgekehrt geordnete Liste [5,4,3,2,1] > even 11 -­‐-­‐ ist die gegebene Zahl gerade False > max 33 2 -­‐-­‐ grössere der beiden Zahlen 33 thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 26 Überblick gewinnen n 
n 
Wie findet man schnell öffentliche/freie Bibliotheken und die darin angebotenen FunkLonen und Datentypen? Hoogle is your friend ... hBp://www.haskell.org/hoogle/ n 
n 
n 
n 
Zentralisiertes Archiv mit SuchfunkLon, in dem alle registrierten APIs dokumenLert sind Suche nach: n  FunkLonsname, z.B. map n  Signatur, z.B. (a -­‐> b) -­‐> [a] -­‐> [b] Eclipse-­‐IntegraLon über EclipseFP Auch mit EMACS integrierbar thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 13 27 Syntax FunkLonsanwendung n 
In der MathemaLk: f(a, b) + cd
Wende die FunkLon f auf die Argumente a und b an und addiere das Ergebnis zum Produkt von c und d. f ist hier ein FunkLonsname; a, b, c, d sind Variablennamen n 
In Haskell: f a b + c * d Argumente von f folgen ohne Klammern; alle OperaLonen durch ein Symbol repräsenLert à * für die MulLplikaLon. thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 28 FunkLonen-­‐ und Operatorrangfolge n 
FunkLonen haben höhere Präzedenz als Operatoren f a + b -­‐-­‐ bedeutet f(a) + b anstatt f(a + b)
n  Es gibt 9 Präzedenzstufen für Operatoren n 
n 
RelaLve Präzedenz mathemaLscher Operatoren entsprechend der mathemaLschen Regeln (* hat höhere Präzedenz als +) FunkLonsanwendung hat Stufe 10 thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 14 29 FunkLonsanwendung -­‐ Beispiele n 
Gegenüberstellung: Mathema2k Haskell f(x)
f x f(x, y)
f x y f(g(x))
f (g x) f(x, g(y))
f x (g y) f(x) g(y)
f x * g y Klammern müssen hier also verwendet werden um die Argumente korrekt zuzuordnen. thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 30 Fixity: AssoziaLvität und Präzedenz n 
Die KombinaLon aus AssoziaLvität und Präzedenz von Operatoren wird auch als Fixity bezeichnet: n 
infixl – Infixoperator, linksassoziaLv, z.B.: a+b+c+d n 
à
((a+b)+c)+d infixr – Infixoperator, rechtsassoziaLv, z.B.: (f.g.h) a à f (g (h a)) n 
infix – Infixoperator, nichtassoziaLv, z.B.: a<b<c à weder (a<b)<c noch a<(b<c) gilt n 
DeklaraLon: infixr 5 ++ -­‐-­‐ rechtsassoz.; Präzedenz 5 infixl 9 . -­‐-­‐ linksassoz.; Präzedenz 9 thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 15 31 Fixity -­‐ Beispiele thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 32 Skript/Programm in GHCi laden myFirstScript.hs double x = x + x quadruple x = double (double x) n 
Reihenfolge egal; DefiniLon irgendwo, aber nicht notwen-­‐
digerweise zuvor Skript mit GHCi laden: > ghci myFirstScript.hs Prelude> :l myFirstScript.hs n 
Prelude.hs und myFirstScript.hs sind dann geladen und die darin definierten FunkLonen können aufgerufen werden. Prelude> quadruple 10 40 Prelude> take (double 2) [1,2,3,4,5,6] [1,2,3,4] thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 16 33 Skript/Programm neu laden n 
Wenn Skript extern (in einem Editor) geändert wurde, muss es mit :reload (bzw. r:) erneut geladen werden um die Änderungen zu akLvieren. Prelude> :r Ok, modules loaded: Main. Prelude> factorial 10 3628800 Prelude> average [1,2,3,4,5] 3 thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 34 Häufig gebrauchte GHCi-­‐Kommandos Kommando
:load name
:reload :edit name
:edit Kurzform
:l name
:r
:e name
:e
Bedeutung lade Skript name aktuelles Skript neu laden ediLere Skript name ediLere aktuelles Skript :info :type expr
:help :quit :i
:t expr :?
:q
InformaLon zu Typ/FunkLon zeige Typ von expr zeige alle Kommandos beende ghci thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 17 35 GHC Compiler hello.hs module Main where main :: IO() main = putStrLn "Hello, World" Programm kompilieren: > ghc –o hello hello.hs > ./hello > Hello, World n  Analog zu vielen anderen Sprachen ist die main FunkLon (opLonal im Modul Main) der EinsLegspunkt in ein Haskell-­‐
Programm. thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 36 Einrückung als Strukturierungselement (i) n 
n 
In Haskell (ähnlich wie in Python) spielt die Einrückung im Quelltext eine Rolle: Blöcke werden durch Einrückung gebildet, d.h. Whitespace (Leerzeichen und Tabulatoren) hat eine abgrenzende SemanLk. In einer Sequenz von DefiniLonen müssen alle DefiniLonen in der exakt selben Spalte beginnen: a = 10 b = 20 c = 30 a = 10 b = 20 c = 30 a = 10 b = 20 c = 30 thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf xs = 10 x = 20 c = 30 April 26, 2013 18 37 Einrückung als Strukturierungselement (ii) n 
Blockbildung durch Einrückung vermeidet die Notwendigkeit spezielle Symbole zur Blockbegrenzung benutzen zu müssen. a = b + c where b = 1 c = 2 d = a * 2 bedeutet implizite Gruppierung a = b + c where {b = 1; c = 2} d = a * 2 explizite Gruppierung thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf K07 April 26, 2013 Haskell 1.  Grundlegende Eigenscha2en 2.  GHCi und GHC 3.  Typsystem thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 19 39 Typen (Wiederholung) n 
Ein Typ ist ein Bezeichner für eine Menge von gleicharLgen Elementen bzw. Werten (engl. values). n 
n 
n 
Eine Klasse ist z.B. eine üblicherweise nichtleere Menge von Objekten (Instanzen) die sich der Klasse zuordnen lassen. Auf einem Typ ist eine Menge von OperaLonen und FunkLonen definiert. In Haskell exisLert z.B. der Typ Bool welcher genau zwei Werte enthält: False thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf True April 26, 2013 40 Typfehler in Haskell n 
Die Anwendung einer FunkLon auf inkompaLble Argumente ist ein Typfehler (engl. type error). > 1 + False Error 1 ist eine Zahl and False ein Bool; jedoch erwartet + zwei Zahlen. thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 20 41 Typen in Haskell n 
Wenn die Auswertung eines Ausdrucks e einen Wert (Ergebnis) vom Typ t liefert, dann ist e vom Typ t
e :: t n 
Jeder syntakLsch korrekte Ausdruck hat in Haskell demzufolge einen Typ, welcher sich automaLsch zur Compilezeit ableiten lässt. Diesen Prozess nennt man Typinferenz (engl. type inference). n 
Haskell hat ein staLsches und strenges Typsystem n  Es können keine Typfehler zur Laufzeit au2reten n  Geringere Fehleranfälligkeit und bessere Laufzeitperformance (da keine Checks zur Laufzeit notwendig sind) thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 42 Typ eines Ausdrucks abfragen n 
Der Typ eines Ausdrucks e kann in GHCi mit dem Kommando :type (bzw. t: als Kurzform) abgefragt werden, ohne dass e dabei ausgewertet wird. > :t "foo" "foo" :: [Char] > :t not False not False :: Bool > :t 3 + 2 3 + 2 :: Num a => a thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 21 43 Allgemeine Datentypen in Haskell Typ Breite/Präzision Bool Int Integer Float2 Double fest (32, 64 bit)1 theoreLsch unbeschränkt einfach (32 bit) doppelt (64 bit) Char String Einzelnes Zeichen ZeichenkeBe (Liste von Zeichen) Rational3 QuoLent zweier Integer-­‐Werte Wertebereich True, False mindestens −229 bis 229−1 -­‐∞ bis +∞ ≈1.175×10-­‐38 bis ≈3.4×1038 ≈4.9406564584124654×10−324 bis ≈1.7976931348623157×10308 UNICODE Complex 1 Maschinenabhängig 2 Laut „Real World Haskell“ Verwendung nicht empfohlen „... is much slower ...“ 3 Ratio Bibliothek thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 44 Listentypen n 
Eine Liste ist eine Folge von Werten desselben Typs: [False,True,False] :: [Bool] [’a’,’b’,’c’,’d’] :: [Char] n 
n 
Generell gilt:
[t] ist der Typ von Listen deren Elemente vom Typ t sind Elemente können wiederum Listen desselben Typs sein: [[’a’],[’b’,’c’]] :: [[Char]] n 
Typ ist unabhängig von der Länge der Liste n  Spezialfall: leere Liste thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf > :t [] [] :: [a] April 26, 2013 22 45 Typeltypen n 
Ein Tupel ist eine Folge von Elementen deren jeweiliger Typ unterschiedlich sein kann: (False,True) :: (Bool,Bool) (False,'a',True) :: (Bool,Char,Bool) ("foo",1,2) :: (Num t1, Num t) => ([Char],t,t1) ('a',('b','c')) :: (Char,(Char,Char)) n 
Generell gilt: (t1, t2, …, tn) ist der Typ von n-­‐Tupeln deren i-­‐tes Element vom Typ ti ist (1 ≤ i ≤ n) Aus dem Typ kann man also die Länge des Tupels ableiten. n 
Spezialfall: leeres Tupel n 
> :t () () :: () thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 46 FunkLonstypen n 
n 
Eine FunkLon ist eine Abbildung von Werten eines Typs auf Werte eines Typs. not :: Bool -­‐> Bool isDigit :: Char -­‐> Bool Generell gilt: t1 -­‐> t2 ist der Typ der Klasse von FunkLonen, die Werte vom Typ t1 auf Werte vom Typ t2 abbilden. n 
Argument und Ergebnistyp add :: (Int,Int) -­‐> Int add (x,y) = x+y sind nicht beschränkt: zeroToN :: Int -­‐> [Int] zeroToN n = [0..n] thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 23 47 Terminologie Typsignatur Funk2ons-­‐ duplizieren :: Bild -­‐> Bild name duplizieren x = neben (spiegeln x) (graustufen x) aktueller Parameter formaler Parameter duplizieren springer Ausdruck (Expression) Funk2onsrumpf duplizieren :: Bild -­‐> Bild duplizieren x = neben (spiegeln x) (graustufen x) Funk2onsdefini2on thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 48 Curryfizierte FunkLonen n 
n 
(i) FunkLonen mit mehreren Argumenten gibt es eigentlich gar nicht in Haskell: Alle FunkLonen haben genau ein Argument (oder gar keines falls sie konstant sind). Eine FunkLon mit mehreren Argumenten lässt sich als FunkLon darstellen, die ein Argument hat und eine FunkLon als Ergebnis liefert. f : (A1 ⇥ · · · ⇥ An ) ! B
f 0 : A1 ! (A2 ! (. . . (An ! B) . . . ))
add' :: Int -­‐> Int -­‐> Int add' x y = x+y add' hat eine Int-­‐Zahl als Argument (x) und liefert eine FunkLon vom Typ Int -­‐> Int. Diese FunkLon wiederum hat eine Int-­‐
Zahl (y) als Argument und liefert eine Int-­‐Zahl als Ergebnis x+y. thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 24 49 Curryfizierte FunkLonen (ii) add' :: Int -­‐> Int -­‐> Int add :: (Int, Int) -­‐> Int n 
n 
n 
add und add' produzieren dasselbe Endergebnis, jedoch nimmt add beide Argumente zur selben Zeit (über ein Tupel), währenddessen add' jeweils nur ein Argument verarbeitet. FunkLonen die jeweils nur ein Argument verarbeiten bezeichnet man als Currifiziert (Prozess selten auch Schönfinkeln genannt). Hauptvorteil theoreLscher Art: formale Beweise der Korrektheit von Programmen wird vereinfacht, wenn alle FunkLon gleichförmig sind. thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 50 Curryfizierte FunkLonen n 
(iii) Beachte: n 
Abbildungspfeil in FunkLonssignatur rechtsassoziaLv: Int -­‐> Int -­‐> Int -­‐> Int Int -­‐> (Int -­‐> (Int -­‐> Int)) n 
FunkLonsapplikaLon linksassoziaLv: mult x y z ((mult x) y) z thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 25 51 ParLelle FunkLonsanwendung n 
Curryfizierung ermöglicht parLelle FunkLonsanwendung: > :t zip3 -­‐-­‐ Funktion die Dreiertupel aus drei Listen bildet zip3 :: [a] -­‐> [b] -­‐> [c] -­‐> [(a, b, c)] > zip3 "foo" "bar" "quux" [('f','b','q'),('o','a','u'),('o','r','u')] > let zip3foo = zip3 "foo" > :type zip3foo zip3foo :: [b] -­‐> [c] -­‐> [(Char, b, c)] > zip3foo "aaa" "bbb" [('f','a','b'),('o','a','b'),('o','a','b')] > zip3foo [1,2,3] [True,False,True] [('f',1,True),('o',2,False),('o',3,True)] thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 52 Polymorphe FunkLonen n 
(i) Eine FunkLon ist polymorph wenn ihr Typ mindestens eine Typvariable enthält. length :: [a] -­‐> Int Für beliebige Typen a liefert length einen Integer als Ergebnis, gegeben eine Liste mit Elementen vom Typ a. Beispiel: > length [False,True] -­‐-­‐ a = Bool 2 > length [1,2,3,4] -­‐-­‐ a = Int 4 thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 26 53 Beispiele polymorpher FunkLonen n 
Zahlreiche FunkLonen aus Prelude.hs (und anderen Bibliotheken) sind polymorph, z.B.: fst :: (a,b) -­‐> a head :: [a] -­‐> a take :: Int -­‐> [a] -­‐> [a] zip :: [a] -­‐> [b] -­‐> [(a,b)] id :: a -­‐> a compare :: Ord a => a -­‐> a -­‐> Ordering thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 54 Überladene FunkLonen n 
Eine polymorphe FunkLon ist überladen wenn ihr Typ mindestens eine Typnebenbedingung (engl. type constraint) enthält. Beispiel: sum :: Num a => [a] -­‐> a Für beliebige Typen a die von Num abgeleitet sind liefert sum ein Ergebnis vom Typ a gegeben eine Liste vom Typ a. > sum [1,2,3] -­‐-­‐ Int 6 > sum [1.1,2.2,3.3] -­‐-­‐ Float 6.6 > sum [’a’,’b’,’c’] -­‐-­‐ Char ERROR -­‐-­‐ kein Num Num ist eine Typklasse die als Oberklasse für numerische Datentypen vorgesehen ist. thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 27 55 Typklassen n 
Typklassen in Haskell sind vergleichbar mit Interfaces in Java. Num Numerische Typen Eq Typen für deren Elemente Gleichheit definiert ist. Ord Typen auf deren Elementen eine Ordnung definiert ist. Beispiele: (+) :: Num a => a -­‐> a -­‐> a (==) :: Eq a => a -­‐> a -­‐> Bool (<) :: Ord a => a -­‐> a -­‐> Bool thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 56 Namensregeln n 
Haskell unterscheidet zwischen Gross-­‐ und Kleinschreibung name naMe Name unterschiedliche Namen/Bezeichner n 
n 
n 
n 
Typen und Konstruktoren beginnen mit einem Grossbuchstabe Typvariablen, FunkLonen und Argumente beginnen mit einem Kleinbuchstabe Zusätzlich darf auch der Unterstrich _ und weitere Sonderzeichen für FunkLonen verwendet werden arg_2 myFun fun1 _myFun Neuere Versionen unterstützen auch UNICODE-­‐Zeichen пять два x’ умножить thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 28 57 Operatoren n 
n 
Sind auch FunkLonen: binärer Operator a b ist zweistellige FunkLon Standardmässig vorhandene binäre/unäre Operatoren n 
n 
n 
(a, b)
ArithmeLsche Operatoren: +, *, ^, -­‐, div, mod, abs, negate Vergleichsoperatoren: beachte: nicht != wie in C/C++/Java >, >=, ==, /=, <=, < Für die DefiniLon neuer Operatoren gelten im Prinzip dieselben Namensregeln wie für FunkLonen n 
n 
Verwendbare Zeichen: ! # $ % & * + . / < = > ? @ \ : -­‐ | ~ ^ Reservierte Namen (Bezeichner): _ .. : :: = \ | <-­‐ -­‐> @ ~ => thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 58 Beispiel: Operator definieren n 
Operator +++ und *** definieren: myOp.hs infixl 6 +++ infixl 7 +++ infixl 7 *** infixl 6 *** (+++) :: Int -­‐> Int -­‐> Int a +++ b = a + 2*b (***) :: Int -­‐> Int -­‐> Int a *** b = a -­‐ 4*b n 
Anwendung (GHCi): Prelude> l: myOp.hs Prelude> 1 +++ 2 *** 3 -­‐19 (1 + 2*(2 – 4*3)) ((1 + 2*2) – 4*3) thorsten möller -­‐ informaLk.unibas.ch/lehre/fs13/cs109/07-­‐haskell.pdf April 26, 2013 29 
Herunterladen