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


best viewed with any browser


http://www.informatik.uni-leipzig.de/~joe/ mailto:joe@informatik.uni-leipzig.de