Vorlesung: Praxis der Funktionalen Programmierung
Einfache Typen
- Wahrheitswerte: Boolean
- Konstruktoren: False, True
- Zeichen: Char
- Konstruktoren: 'a', 'b', '\n', ...
- Ganze Zahlen: Integer (beliebig lang!)
- Konstruktoren: 12343511561356, 0xF0, ...
- Zeichenketten: String
- Ist gar kein einfacher Typ, sondern String = [ Char ], siehe Listen.
Konstruktoren: Listenkonstruktoren und "foo", "bar\n", ...
Listen
Für einen Typ a bezeichnet [a]
den Typ aller Listen mit Elementen vom Typ a.
Eine Liste ist entweder leer, oder sie ist eine Zelle,
die aus einem Kopf mit Typ a und einem Schwanz mit Typ [a] besteht.
Der Datentyp hat also zwei Konstruktoren, [] und (:).
Diese verwenden wir auch in den Mustern. Beispiel:
länge :: [a] -> Integer
länge [] = 0
länge (x : xs) = 1 + länge xs
(Später programmiert man sowas mit einem fold.)
Statt (1 : (2 : (3 : (4 : [])))) schreiben wir kürzer [1, 2, 3, 4].
Tatsächlich können wir dafür sogar [1 .. 4] schreiben.
Im Allgemeinen können wir auch eine Schrittweite angeben:
Prelude> [1, 3 .. 20]
[1,3,5,7,9,11,13,15,17,19]
Anwendung von Listen
Wir verwenden Listen in dem Programm, das Parkettierungen bestimmt
(Quelltext hier).
Die Idee ist, ein polygonal begrenztes Gebiet
durch die Liste seiner Innenwinkel zu beschreiben.
(Die Streckenlängen erwähnen wir nicht, die sind nämlich alle gleich groß).
Zu implementieren ist dann das Aneinanderlegen zweier solcher Gebiete
(d. h. Testen, ob es überhaupt paßt, und Bestimmen der neuen Randkurve).
List Comprehensions
Für das Durchlaufen und Erzeugen von Listen gibt es eine spezielle Syntax,
die sich an der mathematischen Notation für Mengen orientiert.
Wir erkennen sie an dem senkrechten Strich innerhalb von Listenklammern.
Er trennt den Kopf (einen Ausdruck) vom Rumpf (einer Folge
von Generatoren, Filtern und Bindungen)
- Generator
- ist ein Ausdruck nach einem Rückwärtspfeil.
Er bindet die lokale Variable vor dem Pfeil.
Diese ist ab dort im Rumpf sichtbar,
und auch im Kopf der Comprehension.
Beispiele:
Prelude> [ x * x | x <- [ 1, 2, 3, 4 ] ]
[1,4,9,16]
Prelude> [ x * y | x <- [1,2,3], y <- [2,3,5] ]
[2,3,5,4,6,10,6,9,15]
Wir können uns das als geschachtelte Schleifen vorstellen.
- Filter
- ist ein Ausdruck vom Wert Boolean. Beispiel
Prelude> [ x * x | x <- [0,1,2,3,4,5,6,7], 0 < mod x 3 ]
[1,4,16,25,49]
- Bindung
- hat die Form let Bezeichner = Ausdruck.
Der lokale Bezeichner wird gebunden und ist ab dort
und im Kopf sichtbar.
Beispiel:
Prelude> [ y | x <- [0,1,2,3,4,5,6,7], let y = x * x * x ]
[0,1,8,27,64,125,216,343]
Beispiele
Aufgaben
http://www.informatik.uni-leipzig.de/~joe/
mailto:joe@informatik.uni-leipzig.de