Basiskonstrukte von Haskell

Ähnliche Dokumente
Grundprinzipien der funktionalen Programmierung

Was bisher geschah. deklarative Programmierung. funktionale Programmierung (Haskell):

Funktionale Programmierung mit Haskell. Jan Hermanns

Kontrollstrukturen, Pseudocode und Modulo-Rechnung

Java Einführung VARIABLEN und DATENTYPEN Kapitel 2

Funktionale Programmierung

Tutorium - Haskell in der Schule. Ralf Dorn - Dennis Buchmann - Felix Last - Carl Ambroselli

Einführung Datentypen Verzweigung Schleifen Funktionen Dynamische Datenstrukturen. Java Crashkurs. Kim-Manuel Klein

Programmierung in Python

Einführung in die Informatik für Hörer aller Fakultäten II. Andreas Podelski Stephan Diehl Uwe Waldmann

Programmieren in C. C Syntax Datentypen, Operatoren und Kontrollstrukturen. Prof. Dr. Nikolaus Wulff

Einführung in die funktionale Programmierung

Ein erstes Java-Programm

Programmieren in Haskell Einführung

Einfache Ausdrücke Datentypen Rekursive funktionale Sprache Franz Wotawa Institut für Softwaretechnologie

Grundlagen. Die Komponenten eines C Programms. Das erste Programm

Hello World. Javakurs 2014, 1. Vorlesung. Sebastian Schuck. basierend auf der Vorlage von Arne Kappen. wiki.freitagsrunde.org. 3.

Proseminar Funktionales Programmieren. Stephan Kreutzer

Java Einführung Operatoren Kapitel 2 und 3

Diana Lange. Generative Gestaltung Operatoren

II. Grundlagen der Programmierung. 9. Datenstrukturen. Daten zusammenfassen. In Java (Forts.): In Java:

Modul 122 VBA Scribt.docx

1 Syntax von Programmiersprachen

Prinzipien der Softwareentwicklung S. Strahringer

Gliederung. Tutorium zur Vorlesung. Gliederung. Gliederung. 1. Gliederung der Informatik. 1. Gliederung der Informatik. 1. Gliederung der Informatik

7down Zusatzaufgaben. Mathias Ziebarth und Joachim Breitner. 13. März 2008

Lua - Erste Schritte in der Programmierung

Programmieren. 10. Tutorium 4./ 5. Übungsblatt Referenzen

Programmieren in C. Macros, Funktionen und modulare Programmstruktur. Prof. Dr. Nikolaus Wulff

Programmierung in C. Grundlagen. Stefan Kallerhoff

Funktionale Programmierung

Primitive Datentypen

Funktionale Programmierung. Frank Adler

Verträge für die funktionale Programmierung Design und Implementierung

Einführung in die C++ Programmierung für Ingenieure

Noch für heute: primitive Datentypen in JAVA. Primitive Datentypen. Pseudocode. Dezimal-, Binär- und Hexadezimalsystem. der logische Typ boolean

Einführung in das Programmieren Prolog Sommersemester Teil 2: Arithmetik. Version 1.0

Kapitel 11: Wiederholung und Zusammenfassung

Beispiele: (Funktionen auf Listen) (3) Bemerkungen: Die Datenstrukturen der Paare (2) Die Datenstrukturen der Paare

Eine Einführung in C-Funktionen

1 Polymorphie (Vielgestaltigkeit)

CGI Programmierung mit Ha. Markus Schwarz

Programmierkurs Java

Programmieren in C. Felder, Schleifen und Fließkommaarithmetik. Prof. Dr. Nikolaus Wulff

Einführung in die Java- Programmierung

Einführung in die Java- Programmierung

Funktionale Programmierung Blatt 1

Einführung in die C-Programmierung

Das erste Programm soll einen Text zum Bildschirm schicken. Es kann mit jedem beliebigen Texteditor erstellt werden.

Deklarationen in C. Prof. Dr. Margarita Esponda

Fragen. f [ ] = [ ] f (x : y : ys) = x y : f ys f (x : xs) = f (x : x : xs) Wozu evaluiert f [1, 2, 3] (Abkürzung für f (1 : 2 : 3 : [ ]))?

Funktionale Programmierung ALP I. Funktionen höherer Ordnung. Teil 2 SS Prof. Dr. Margarita Esponda. Prof. Dr.

Propädeutikum zur Programmierung

Java 7. Elmar Fuchs Grundlagen Programmierung. 1. Ausgabe, Dezember 2011 JAV7

Definieren Sie eine Funktion circlearea zur Berechnung der Fläche eines Kreises mit gegebenen Radius (Float).

Objektorientiertes Programmieren für Ingenieure

Was bisher geschah Funktionale Programmierung in Haskell: Algebraische Datentypen Pattern Matching Polymorphie Typklassen Rekursive Datentypen:

Erster Kontakt mit Java und Pseudocode

Numerische Datentypen. Simon Weidmann

ALP I. Funktionale Programmierung

Objective-C CheatSheet

Die Programmiersprache C

VBA-Programmierung: Zusammenfassung

4. Datentypen. Einleitung Eingebaute Datentypen. Konversion / Type-Cast. Operatoren. Übersicht Die Datentypen char, float und double Standardwerte

Funktionale Programmierung mit Haskell

Programmieren in C. Rekursive Funktionen. Prof. Dr. Nikolaus Wulff

Wintersemester Maschinenbau und Kunststofftechnik. Informatik. Tobias Wolf Seite 1 von 16

Kurzeinführung in C. Johannes J. Schneider

Ruby. Erfinder: Yukihiro Matsumoto Japan 1993 Einflüsse: Smalltalk Perl Eigenschaften: Objektorientiert Interpretiert

Der Aufruf von DM_in_Euro 1.40 sollte die Ausgabe 1.40 DM = Euro ergeben.

Objektorientierte Programmierung mit Python Polymorphismus und Vererbung. Eltern

TECHNISCHE UNIVERSITÄT MÜNCHEN FAKULTÄT FÜR INFORMATIK

C allgemein. C wurde unter und für Unix entwickelt. Vorläufer sind BCPL und B.

Zweite Möglichkeit: Ausgabe direkt auf dem Bildschirm durchführen:

Funktionale Programmierung

Java-Vorkurs Wintersemester 15/16

Eine Einführung in die funktionale Programmierung mit Haskell

Python Programmierung. Dipl.-Ing.(FH) Volker Schepper

Dr. Monika Meiler. Inhalt

Erster Bug: eine Motte

Informatik. Studiengang Chemische Technologie. Michael Roth WS 2012/2013. Hochschule Darmstadt -Fachbereich Informatik-

Grundlagen der Programmierung Prof. H. Mössenböck. 3. Verzweigungen

Ausarbeitung des Interpreter Referats

Programmiertechnik Operatoren, Kommentare, Ein-/Ausgabe

Hochschule Darmstadt Informatik-Praktikum (INF 1) WS 2014/2015 Wirtschaftsingenieur Bachelor 4. Aufgabe Datenstruktur, Dateieingabe und -ausgabe

Propädeutikum zur Programmierung

Programmierkurs: Delphi: Einstieg

HASKELL KURS RALF HINZE. Institut für Informatik III Universität Bonn Römerstraße Bonn Germany

Hochschule Darmstadt Informatik-Praktikum (INF 1) WS 2015/2016 Wirtschaftsingenieur Bachelor 5. Aufgabe Datenstruktur, Dateieingabe und -ausgabe

! Sprachkonstrukte für den funktionalen Programmierstil in Java! ! Programmiertechniken:! ! Terminierung und partielle Korrektheit!

Formale Sprachen, reguläre und kontextfreie Grammatiken

IT-Zertifikat: Allgemeine Informationstechnologien II PHP

Anweisungsblöcke (dazu zählen auch Programme) werden in geschweifte Klammern eingeschlossen.

Programmieren in C. Operatoren, Variablen und deren Sichtbarkeit. Prof. Dr. Nikolaus Wulff

Funktionale Programmierung mit Haskell

Einführung in die Programmierung (EPR)

Praktikum zu Einführung in die Informatik für LogWiIngs und WiMas Wintersemester 2015/16. Vorbereitende Aufgaben

Transkript:

Basiskonstrukte von Haskell PD Dr. David Sabel Goethe-Universität Frankfurt am Main 29. September 2015

Basistypen und Operationen Ganzzahlen: Int = Ganzzahlen beschränkter Länge Integer = Ganzzahlen beliebiger Länge Gleitkommazahlen: Darstellung mit Punkt, z.b. 10.25 Float = Fließkommazahlen Double = Fließkommazahlen mit doppelter Genauigkeit Arithmetische Operationen: Addition (+), Subtraktion (-), Multiplikation (*), Division (/) Ganzzahlige Division: mod, div, divmod D. Sabel Basiskonstrukte von Haskell 29. September 2015 2/34

Wahrheitswerte: Der Datentyp Bool Werte (Datenkonstruktoren) vom Typ Bool: True und False Basisoperationen (Funktionen): Logische Negation: not Logisches Und: a && b Logisches Oder: a b Arithmetische Vergleiche: Gleichheit (==), Ungleichheit (/=), größer (>), größer oder gleich (>=), kleiner (<), kleiner oder gleich (<=) D. Sabel Basiskonstrukte von Haskell 29. September 2015 3/34

Zeichen und Zeichenketten Der Typ Char repräsentiert Zeichen Darstellung: Zeichen in einfache Anführungszeichen, z.b. A Zeichenketten: Typ String Dastellung in doppelten Anfühungszeichen, z.b. "Hallo". Genauer ist der Typ String gleich zu [Char] d.h. eine Liste von Zeichen D. Sabel Basiskonstrukte von Haskell 29. September 2015 4/34

Infix- und Präfixoperatoren Präfix-Operatoren infix verwenden: In Hochkommata setzen ( + ` z.b. 10 mod 3 Infix-Operatoren präfix verwenden: In runde Klammern setzen z.b. (+) 5 6 ) D. Sabel Basiskonstrukte von Haskell 29. September 2015 5/34

Funktionen Definition (mathematisch): Seien D und Z Mengen. Eine Funktion f : D Z ordnet jedem Element x D ein Element y Z zu. D nennt man den Definitionsbereich und Z den Zielbereich. 3 1 2 6 3 1 4 2 5 D. Sabel Basiskonstrukte von Haskell 29. September 2015 6/34

Funktionen Definition (mathematisch): Seien D und Z Mengen. Eine Funktion f : D Z ordnet jedem Element x D ein Element y Z zu. D nennt man den Definitionsbereich und Z den Zielbereich. Beispiel: double : Z }{{} Definitionsbereich double(x) = x + x Z }{{} Zielbereich D. Sabel Basiskonstrukte von Haskell 29. September 2015 6/34

Funktionen Definition (mathematisch): Seien D und Z Mengen. Eine Funktion f : D Z ordnet jedem Element x D ein Element y Z zu. D nennt man den Definitionsbereich und Z den Zielbereich. Beispiel: double : Z }{{} Definitionsbereich double(x) = x + x Z }{{} Zielbereich In Haskell, Funktionstypen: Typ 1 -> Typ 2 double :: Integer -> Integer double x = x + x D. Sabel Basiskonstrukte von Haskell 29. September 2015 6/34

Mehrstellige Funktionen Möglichkeit 1: Definitionsbereich ist eine Menge von Tupeln add : (Z Z) }{{}}{{} Z Definitionsbereich Zielbereich add(x, y) = x + y (1,1) (1,2) (2,1) 6 1 3 2 4 5 Verwendung: add(1, 2) D. Sabel Basiskonstrukte von Haskell 29. September 2015 7/34

Mehrstellige Funktionen: Currying Möglichkeit 2: (Currying) Statt Funktion mit n-argumenten, Funktion mit einem Argument, Rückgabe: ist Funktion! add : }{{} Z (Z Z) }{{} Definitionsbereich Zielbereich add x y = x + y 2 2 3 1 1 2 3 1 3 4 2 4 5 3 D. Sabel Basiskonstrukte von Haskell 29. September 2015 8/34

Mehrstellige Funktionen (3) Möglichkeit 2: (Currying) Statt Funktion mit n-argumenten, Funktion mit einem Argument, Rückgabe: ist Funktion! add : }{{} Z (Z Z) }{{} Definitionsbereich Zielbereich add x y = x + y Vorteil ggü. Variante 1: Man kann partiell anwenden, z.b. add 2 Variante 2 wird in Haskell fast immer verwendet! add :: Integer -> (Integer -> Integer) add x y = x + y D. Sabel Basiskonstrukte von Haskell 29. September 2015 9/34

Mehrstellige Funktionen (3) Möglichkeit 2: (Currying) Statt Funktion mit n-argumenten, Funktion mit einem Argument, Rückgabe: ist Funktion! add : }{{} Z (Z Z) }{{} Definitionsbereich Zielbereich add x y = x + y Vorteil ggü. Variante 1: Man kann partiell anwenden, z.b. add 2 Variante 2 wird in Haskell fast immer verwendet! add :: Integer -> (Integer -> Integer) add x y = x + y -> in Haskell ist rechts-assoziativ: a -> b -> c = a -> (b -> c) Daher kann man Klammern weglassen. D. Sabel Basiskonstrukte von Haskell 29. September 2015 9/34

Mehrstellige Funktionen (3) Möglichkeit 2: (Currying) Statt Funktion mit n-argumenten, Funktion mit einem Argument, Rückgabe: ist Funktion! add : }{{} Z (Z Z) }{{} Definitionsbereich Zielbereich add x y = x + y Vorteil ggü. Variante 1: Man kann partiell anwenden, z.b. add 2 Variante 2 wird in Haskell fast immer verwendet! add :: Integer -> Integer -> Integer add x y = x + y -> in Haskell ist rechts-assoziativ: a -> b -> c = a -> (b -> c) Daher kann man Klammern weglassen. D. Sabel Basiskonstrukte von Haskell 29. September 2015 9/34

Funktionstypen Einfacher: f erwartet n Eingaben, dann ist der Typ von f : f :: Typ 1 }{{} Typ des 1. Arguments -> Typ 2 }{{} Typ des 2. Arguments ->... -> Typ n }{{} Typ des n. Arguments -> Typ n+1 }{{} Typ des Ergebnisses -> in Funktionstypen ist rechts-geklammert (&&) :: Bool -> Bool -> Bool entspricht (&&) :: Bool -> (Bool -> Bool) und nicht (&&) :: (Bool -> Bool) -> Bool D. Sabel Basiskonstrukte von Haskell 29. September 2015 10/34

Funktionen: Beispiele Beispiel: mod und div mod: Rest einer Division mit Rest div: Ganzzahliger Anteil der Division mit Rest Typen von mod und div: mod :: Integer -> Integer -> Integer div :: Integer -> Integer -> Integer In Wirklichkeit: Prelude> :type mod mod :: (Integral a) => a -> a -> a Prelude> :type div div :: (Integral a) => a -> a -> a In etwa: Für alle Typen a die Integral-Typen sind, hat mod den Typ a -> a -> a D. Sabel Basiskonstrukte von Haskell 29. September 2015 11/34

Weitere Funktionen und ihre Typen Prelude> :type (==) (==) :: (Eq a) => a -> a -> Bool Prelude> :type (<) (<) :: (Ord a) => a -> a -> Bool Prelude> :type (+) (+) :: (Num a) => a -> a -> a Prelude> :type (/) (/) :: Fractional a => a -> a -> a D. Sabel Basiskonstrukte von Haskell 29. September 2015 12/34

Typgerecht programmieren Die Typen müssen stets passen, sonst gibt s einen Typfehler: Prelude> :type not not :: Bool -> Bool Prelude> not C <interactive>:1:4: Couldn t match expected type Bool against inferred type Char In the first argument of not, namely C In the expression: not C In the definition of it : it = not C (Unerwartete) Fehlermeldung: Prelude> not 5 <interactive>:1:4: No instance for (Num Bool) arising from the literal 5 at <interactive>:1:4 Possible fix: add an instance declaration for (Num Bool) In the first argument of not, namely 5 In the expression: not 5 In the definition of it : it = not 5 D. Sabel Basiskonstrukte von Haskell 29. September 2015 13/34

Funktionen selbst definieren double x = x + x D. Sabel Basiskonstrukte von Haskell 29. September 2015 14/34

Funktionen selbst definieren double x = x + x Allgemein: wobei funktion Name par 1... par n = Haskell Ausdruck par i : Formale Parameter, z.b. Variablen x, y,... Die par i dürfen rechts im Haskell Ausdruck verwendet werden funktion Name muss mit Kleinbuchstaben oder einem Unterstrich beginnen D. Sabel Basiskonstrukte von Haskell 29. September 2015 14/34

Funktionen selbst definieren double :: Integer -> Integer double x = x + x Allgemein: wobei funktion Name par 1... par n = Haskell Ausdruck par i : Formale Parameter, z.b. Variablen x, y,... Die par i dürfen rechts im Haskell Ausdruck verwendet werden funktion Name muss mit Kleinbuchstaben oder einem Unterstrich beginnen Man darf auch den Typ angeben! D. Sabel Basiskonstrukte von Haskell 29. September 2015 14/34

Fallunterscheidung: if-then-else Syntax: if b then e 1 else e 2 Beispiel: doubleeven :: Integer -> Integer doubleeven x = if even x then double x else x even testet, ob eine Zahl gerade ist: even x = x mod 2 == 0 *Main> :reload [1 of 1] Compiling Main ( programme/einfachefunktionen.hs ) Ok, modules loaded: Main. *Main> doubleeven 50 100 *Main> doubleeven 17 17 D. Sabel Basiskonstrukte von Haskell 29. September 2015 15/34

Guards Guards (Wächter): Boolesche Ausdrücke, die die Definition der Funktion festlegen f x1... xm 1. Guard = e1... n. Guard = en Abarbeitung von oben nach unten Erster Guard, der zu True auswertet, bestimmt die Definition. doubleeven a even a = double a otherwise = a Vordefiniert: otherwise = True D. Sabel Basiskonstrukte von Haskell 29. September 2015 16/34

Einstiegsaufgabe zu Funktionen Aufgabe Implementiere eine Funktion max3 in Haskell, die das Maximum von drei Ganzzahlen berechnet. Strukturiertes Vorgehen zur Problemlösung: Was sind die Eingaben und Ausgaben von max3? Wie lautet der Typ von max3 in Haskell? Wie findet man das Maximum von drei Zahlen a, b, c? Wie implementiert man max3 in Haskell? D. Sabel Basiskonstrukte von Haskell 29. September 2015 17/34

Einstiegsaufgabe zu Funktionen Aufgabe Implementiere eine Funktion max3 in Haskell, die das Maximum von drei Ganzzahlen berechnet. Strukturiertes Vorgehen zur Problemlösung: Was sind die Eingaben und Ausgaben von max3? Eingabe: Drei Zahlen vom Typ Integer Ausgabe: Eine Zahl vom Typ Integer Wie lautet der Typ von max3 in Haskell? Wie findet man das Maximum von drei Zahlen a, b, c? Wie implementiert man max3 in Haskell? D. Sabel Basiskonstrukte von Haskell 29. September 2015 17/34

Einstiegsaufgabe zu Funktionen Aufgabe Implementiere eine Funktion max3 in Haskell, die das Maximum von drei Ganzzahlen berechnet. Strukturiertes Vorgehen zur Problemlösung: Was sind die Eingaben und Ausgaben von max3? Eingabe: Drei Zahlen vom Typ Integer Ausgabe: Eine Zahl vom Typ Integer Wie lautet der Typ von max3 in Haskell? max3 :: Integer -> Integer -> Integer -> Integer Wie findet man das Maximum von drei Zahlen a, b, c? Wie implementiert man max3 in Haskell? D. Sabel Basiskonstrukte von Haskell 29. September 2015 17/34

Einstiegsaufgabe zu Funktionen Aufgabe Implementiere eine Funktion max3 in Haskell, die das Maximum von drei Ganzzahlen berechnet. Strukturiertes Vorgehen zur Problemlösung: Was sind die Eingaben und Ausgaben von max3? Eingabe: Drei Zahlen vom Typ Integer Ausgabe: Eine Zahl vom Typ Integer Wie lautet der Typ von max3 in Haskell? max3 :: Integer -> Integer -> Integer -> Integer Wie findet man das Maximum von drei Zahlen a, b, c? Z.B. berechne erst das Maximum von a und b, und anschließend das Maximum des Ergebnisses und c Wie implementiert man max3 in Haskell? D. Sabel Basiskonstrukte von Haskell 29. September 2015 17/34

Varianten von max3 max3 a b c = if a >= b then if a >= c then a else c else if b >= c then b else c Mit Guards: max3 a b c a >= b && a >= c = a b >= a && b >= c = b otherwise = c Mit max2 max2 a b a >= b = a otherwise = b max3 a b c = max2 (max2 a b) c D. Sabel Basiskonstrukte von Haskell 29. September 2015 18/34

Let-Ausdrücke: Lokale Definitionen Beispiel: let f 1 x 1,1... x n,1 = Ausdruck 1 f 2 x 1,2... x n,2 = Ausdruck 2... f m x 1,m... x n,m = Ausdruck m in Ausdruck max3 a b c = let max2 x y = if x >= y then x else y maxab = max2 a b in max2 maxab c D. Sabel Basiskonstrukte von Haskell 29. September 2015 19/34

where-ausdrücke: nachgestellte lokale Definitionen Beispiel: fun y 1... y m = e where f 1 x 1,1... x n,1 = Ausdruck 1 f 2 x 1,2... x n,2 = Ausdruck 2... f m x 1,m... x n,m = Ausdruck m max3 a b c = max2 maxab c where max2 x y x >= y = y otherwise = y maxab = max a b D. Sabel Basiskonstrukte von Haskell 29. September 2015 20/34

Anonyme Funktionen Lambda-Ausdrücke λx.e stellen anonyme Funktionen dar Analog zu f x = e, nur dass die Funktion keinen Namen hat Haskell-Notation \x -> e Mehrstellige Lambda-Ausdrücke: \x1 x2... xn -> e Beispiel: Die Funktion double als anonyme Funktion: \x -> x + x D. Sabel Basiskonstrukte von Haskell 29. September 2015 21/34

Higher-Order Funktionen D.h.: Rückgabewerte dürfen in Haskell auch Funktionen sein Auch Argumente (Eingaben) dürfen Funktionen sein: applyandadd f x y = (f x) + (f y) (.) f g x = f (g x) *Main> applyandadd double 10 20 60 *Main> applyandadd (\a -> a^2) 3 4 25 *Main> (even. double) 3 True D. Sabel Basiskonstrukte von Haskell 29. September 2015 22/34

Nochmal Typen Typ von applyandadd applyandadd :: (Integer -> Integer) -> Integer -> Integer -> Integer applyandadd f x y = (f x) + (f y) D. Sabel Basiskonstrukte von Haskell 29. September 2015 23/34

Nochmal Typen Typ von applyandadd applyandadd :: (Integer -> Integer) }{{} Typ von f applyandadd f x y = (f x) + (f y) -> Integer }{{} Typ von x -> Integer }{{} Typ von y -> Integer }{{} Typ des Ergebnisses D. Sabel Basiskonstrukte von Haskell 29. September 2015 23/34

Nochmal Typen Typ von applyandadd applyandadd :: (Integer -> Integer) -> Integer -> Integer -> Integer applyandadd f x y = (f x) + (f y) Achtung: Im Typ (Integer -> Integer) -> Integer -> Integer -> Integer darf man die Klammern nicht weglassen: Integer -> Integer -> Integer -> Integer -> Integer denn das entspricht Integer -> (Integer -> (Integer -> (Integer -> Integer))). D. Sabel Basiskonstrukte von Haskell 29. September 2015 23/34

Polymorphe Typen twice :: (a -> a) -> a -> a twice f x = f (f x) Da Typvariablen in Haskell erlaubt sind, spricht man von polymorphen Typen Für Typvariablen kann man Typen einsetzen! D. Sabel Basiskonstrukte von Haskell 29. September 2015 24/34

Polymorphe Typen twice :: (a -> a) -> a -> a twice f x = f (f x) Da Typvariablen in Haskell erlaubt sind, spricht man von polymorphen Typen z.b. a = Int Für Typvariablen kann man Typen einsetzen! twice :: (a -> a) -> a -> a D. Sabel Basiskonstrukte von Haskell 29. September 2015 24/34

Polymorphe Typen twice :: (a -> a) -> a -> a twice f x = f (f x) Da Typvariablen in Haskell erlaubt sind, spricht man von polymorphen Typen z.b. a = Int Für Typvariablen kann man Typen einsetzen! twice :: (Int -> Int) -> Int -> Int D. Sabel Basiskonstrukte von Haskell 29. September 2015 24/34

Polymorphe Typen twice :: (a -> a) -> a -> a twice f x = f (f x) Da Typvariablen in Haskell erlaubt sind, spricht man von polymorphen Typen z.b. a = Int z.b. a = Bool Für Typvariablen kann man Typen einsetzen! twice :: (Int -> Int) -> Int -> Int twice :: (a -> a) -> a -> a D. Sabel Basiskonstrukte von Haskell 29. September 2015 24/34

Polymorphe Typen twice :: (a -> a) -> a -> a twice f x = f (f x) Da Typvariablen in Haskell erlaubt sind, spricht man von polymorphen Typen z.b. a = Int z.b. a = Bool Für Typvariablen kann man Typen einsetzen! twice :: (Int -> Int) -> Int -> Int twice :: (Bool -> Bool) -> Bool -> Bool D. Sabel Basiskonstrukte von Haskell 29. September 2015 24/34

Polymorphe Typen twice :: (a -> a) -> a -> a twice f x = f (f x) Da Typvariablen in Haskell erlaubt sind, spricht man von polymorphen Typen z.b. a = Int z.b. a = Bool Für Typvariablen kann man Typen einsetzen! twice :: (Int -> Int) -> Int -> Int twice :: (Bool -> Bool) -> Bool -> Bool z.b. a = Char -> Char twice :: (a -> a) -> a -> a D. Sabel Basiskonstrukte von Haskell 29. September 2015 24/34

Polymorphe Typen twice :: (a -> a) -> a -> a twice f x = f (f x) Da Typvariablen in Haskell erlaubt sind, spricht man von polymorphen Typen z.b. a = Int z.b. a = Bool Für Typvariablen kann man Typen einsetzen! twice :: (Int -> Int) -> Int -> Int twice :: (Bool -> Bool) -> Bool -> Bool z.b. a = Char -> Char twice::((char->char)->(char->char))->(char->char)->(char->char) D. Sabel Basiskonstrukte von Haskell 29. September 2015 24/34

Rekursion Beispiel: Rekursionsanfang: Der Fall, für den sich die Funktion nicht mehr selbst aufruft, sondern abbricht Rekursionsschritt: Der rekursive Aufruf fakultaet x = if x <= 1 then 1 -- Rekursionsanfang else x*(fakultaet (x-1)) -- Rekursionsschritt Problemlösen mit Rekursion: Rekursionsanfang: Der einfache Fall, für den man die Lösung direkt kennt. Rekursionsschritt: Man löst ganz wenig selbst, bis das Problem etwas kleiner ist. Das (immer noch große) Restproblem erledigt die Rekursion, D. Sabel Basiskonstrukte von Haskell 29. September 2015 25/34

Aufgabe zur Rekursion Aufgabe Die Quersumme einer nichtnegativen Ganzahl ist die Summe ihrer Ziffern. Implementiere in Haskell eine rekursive Funktion, welche die Quersumme einer nichtnegativen Ganzzahl berechnet. Was ist der Rekursionsanfang? Was ist der Rekursionsschritt? Welche Teilprobleme sind zu lösen? D. Sabel Basiskonstrukte von Haskell 29. September 2015 26/34

Aufgabe zur Rekursion Aufgabe Die Quersumme einer nichtnegativen Ganzahl ist die Summe ihrer Ziffern. Implementiere in Haskell eine rekursive Funktion, welche die Quersumme einer nichtnegativen Ganzzahl berechnet. Was ist der Rekursionsanfang? Die Zahl ist einstellig. Was ist der Rekursionsschritt? Rekursiv die Quersumme der Zahl ohne letzte Ziffer berechnen und die letzte Ziffer hinzuaddieren. Welche Teilprobleme sind zu lösen? testen, ob eine Zahl einstellig ist: Division mit Rest durch 10 ergibt 0 als ganzzahligen Anteil letzte Ziffer einer Zahl bestimmen: Rest der Division mit Rest durch 10 Zahl ohne letzte Ziffer berechnen: Ganzzahliger Anteil der Division durch 10 D. Sabel Basiskonstrukte von Haskell 29. September 2015 26/34

Quersumme in Haskell quersumme x = if x div 10 == 0 then x mod 10 -- Zahl ist einstellig else (x mod 10) + (quersumme (x div 10)) Variante mit divmod und let quersumme x = let (d,r) = divmod x 10 in if d == 0 then r else r + (quersumme d) D. Sabel Basiskonstrukte von Haskell 29. September 2015 27/34

Pattern matching (auf Zahlen) N-maliges Verdoppeln: double_n_times :: Integer -> Integer -> Integer double_n_times x n = if n == 0 then x else double_n_times (double x) (n-1) Man darf statt Variablen auch Pattern in der Funktionsdefinition verwenden, und mehrere Definitionsgleichungen angeben. Die Pattern werden von oben nach unten abgearbeitet. double_n_times2 :: Integer -> Integer -> Integer double_n_times2 x 0 = x double_n_times2 x n = double_n_times2 (double x) (n-1) Falsch: double_n_times2 :: Integer -> Integer -> Integer double_n_times2 x n = double_n_times2 (double x) (n-1) double_n_times2 x 0 = x D. Sabel Basiskonstrukte von Haskell 29. September 2015 28/34

Die Error-Funktion double_n_times3 :: Integer -> Integer -> Integer double_n_times3 x n n == 0 = x otherwise = double_n_times3 (double x) (n-1) Was passiert bei negativem n? D. Sabel Basiskonstrukte von Haskell 29. September 2015 29/34

Die Error-Funktion double_n_times3 :: Integer -> Integer -> Integer double_n_times3 x n n == 0 = x otherwise = double_n_times3 (double x) (n-1) Was passiert bei negativem n? error :: String -> a double_n_times4 :: Integer -> Integer -> Integer double_n_times4 x n n < 0 = error "Negatives Verdoppeln verboten!" n == 0 = x otherwise = double_n_times4 (double x) (n-1) *Main> double_n_times4 10 (-10) *** Exception: in double_n_times4: negatives Verdoppeln ist verboten D. Sabel Basiskonstrukte von Haskell 29. September 2015 29/34

Ein- und Ausgabe Seiteneffekte liegen außerhalb der reinen funktionalen Welt In Haskell: Monadisches IO Sehr analog zu imperativem Programmieren Typ einer IO-Aktion: IO a bezeichnet eine Seiteneffekt-behaftet Berechnung mit Rückgabe vom Typ a IO-Aktion mit Typ IO () entspricht keiner Rückgabe return :: a -> IO a liefert IO-Aktion, die das Argument zurückliefert. D. Sabel Basiskonstrukte von Haskell 29. September 2015 30/34

Ein- und Ausgabe: do-notation Mit do kann sequentiell Seiteneffekt-behaftet programmiert werden. Auf Ergebnisse einer Berechnung kann nur im do-block mit do... result <- monadischeberechnung... zugegriffen werden. es gibt keine Möglichkeit, dies außerhalb zu tun! insbesondere keine Funktion IO a -> a D. Sabel Basiskonstrukte von Haskell 29. September 2015 31/34

Primitive IO-Aktionen getchar :: IO Char getline :: IO String putchar :: Char -> IO () putstrln :: String -> IO () Beispiel: echo echo :: IO () echo = do line <- getline putstrln line D. Sabel Basiskonstrukte von Haskell 29. September 2015 32/34

File-IO Haskell unterstützt lazy-io Beispiele: Datei lazy einlesen: readfile :: FilePath -> IO String Datei schreiben: writefile :: FilePath -> String -> IO () copy :: FilePath -> FilePath -> IO () copy from to = do content <- readfile from writefile to content cat :: FilePath -> IO () cat file = do content <- readfile file putstrln content D. Sabel Basiskonstrukte von Haskell 29. September 2015 33/34

Bibliotheken Haskell hat ein hierarchisches Modul-System Bibliotheken (siehe z.b. haskell.org/hackage) liegen in der Hierarchie vor Zeichenverarbeitung: Data.Char Listenprogrammierung: Data.List Einbinden von Bibliotheken mit dem Schlüsselwort import Modulname am Anfang der Quellcodedatei Modul laden im GHCi: :m + Modulname Z.B. import Data.Char copyandupper from to = do content <- readfile from writefile to (map toupper content) D. Sabel Basiskonstrukte von Haskell 29. September 2015 34/34