Manuel M. T. Chakravarty Gabriele C. Keller Einführung in die Programmierung mit Haskell ein Imprint von Pearson Education München • Boston • San Francisco • Harlow, England Don Mills, Ontario • Sydney • Mexico City Madrid • Amsterdam Inhaltsverzeichnis Vorwort Software Danksagung Kapitel 1 Kapitel 2 Kapitel 3 Kapitel 4 Kapitel 5 Kapitel 6 9 9 10 Einführung 11 1.1 1.2 11 13 Programmiersprachen Werte, Funktionen und Typen Programmierumgebung 21 2.1 2.2 21 23 Die Betriebssystemfamilie Unix Haskell-Programme ausführen Grundlegende Kontrollstrukturen und Typen 25 3.1 3.2 3.3 3.4 3.5 3.6 25 26 28 29 32 34 Programme werden aus Modulen gebildet Verzweigungen im Programmablauf Zuweisungen Tupel: Kombinationen verschiedener Datenelemente Listen: Viele Werte desselben Typs Layout Rekursion 37 4.1 4.2 4.3 4.4 37 41 42 47 Rekursion über Zahlen Partielle Funktionen Rekursion und Listen Polymorphie und Überladen von Operationen Listen und Funktionen höherer Ordnung 51 5.1 5.2 5.3 5.4 51 57 58 58 Daten aus einer Liste extrahieren Listenelemente aktualisieren Ein kurzer Blick auf das Sortieren Funktionen höherer Ordnung Die Unix-Programmierumgebung 65 6.1 6.2 6.3 6.4 6.5 6.6 6.7 65 69 72 73 75 77 84 Unix Unix – kleine Tools und wie man sie kombiniert Umleitung und Pipeline Interpreter und Compiler Shell-Skripte Ein Autotest-Skript Skripte für den automatischen Test 6 6 Kapitel 7 Kapitel 8 Inhaltsverzeichnis Eingabe und Ausgabe 87 7.1 7.2 7.3 7.4 87 89 97 97 Benutzerdefinierte Datentypen 103 8.1 8.2 8.3 8.4 8.5 103 104 106 109 8.6 Kapitel 9 Noch einmal: Compiler versus Interpreter Eingabe-/Ausgabe-Aktionen Datei-Eingabe/-Ausgabe Beispiele Parametrische Typsynonyme Aufzählungstypen Parametrisierte Alternativen Rekursive Datentypdefinitionen Intermezzo: Die Bedeutung der verschiedenen Syntaxvarianten Typklassen für benutzerdefinierte Datentypen 111 113 Formale Überlegungen 117 9.1 9.2 9.3 Programmkalkulation Mit Lemmata und Generalisierung arbeiten Programmherleitung 118 127 131 Kapitel 10 Modularisierung und Programmdekomposition 137 10.1 Modulares Design 10.2 Geltungsbereich und Sichtbarkeit von Namen Kapitel 11 Software-Komplexität 11.1 11.2 11.3 11.4 Analyse der Komplexität Die /-Notation Effizientere Sortieralgorithmen Rekurrenzrelationen auflösen Kapitel 12 Baumstrukturen 12.1 Datenstrukturen und Effizienz 12.2 AVL-Bäume 12.3 Trie-Strukturen Kapitel 13 Arithmetische Ausdrücke auswerten 13.1 Geschlossene Ausdrücke auswerten 13.2 Ausdrücke mit Variablen 13.3 Funktionsdefinitionen einfügen 138 143 149 150 156 158 164 165 165 170 175 179 179 182 185 Inhaltsverzeichnis Anhang A Anhang B 7 Gemeinsame Eigenschaften 189 A.1 189 Einige grundlegende Eigenschaften Zusätzlicher Programmcode 191 B.1 191 Der Quellcode für den Ausdrucksparser Sachregister 195 7