2. Funktionale Programmierung mit Haskell


[ Seminar "XML und Funktionale Programmierung" ] ... [ 1. Einführung ] ... [ 3. Datenstruktur ]

Übersicht


Einleitung

Für das Verständnis dieser Seminararbeit ist es notwendig, Kenntnis über einige Grundlagen der Funktionalen Programmierung mit Haskell zu haben. Im Nachfolgenden sollen nur die wichtigsten Aspekte angesprochen werden, nämliche solche die auch für die Verarbeitung von XML und zum Verständnis des Ansatzes der Haskell XML Toolbox entscheidend sind.

Das Paradigma der Funktionale Programmiersprachen ist sehr stark an die Mathematik angelehnt und damit sehr formal. Die Sprache erlaubt es, die Korrektheit von Programmen mit Hilfe von aus der Mathematik bekannten Beweisverfahren zu überprüfen. Bei der Programmierung mit Haskell muss man sich nicht um das Speichermanagement oder Ähnliches kümmern. Was bei der Entwicklung mit Haskell zählt, ist nicht das "Wie" ein Programm implementiert ist, sondern "Was" berechnet werden soll.

In Haskell existieren wie in der Mathematik keine Variablen und damit auch keine Variablenzuweisung. Dies führt damit nicht zu unerwünschten Seiteneffekten. Des Weiteren ist Haskell streng getypt und bedient sich der Lazy Evaluation, also der Auswertung von Ausdrücken nur bei Bedarf.

Die zwei wichtigsten Eigenschaften oder Mechanismen, die zur Verarbeitung von XML genutzt werden sind Kombinatoren und Funktionen höherer Ordnung.


2.2. Funktionen

Funktionen sind - wie der Name vermuten läßt - die wichtigste Struktur in der Funktionalen Programmierung mit Haskell. Man unterscheidet dabei die Funktionsdefinition und die Funktionsapplikation.

Beispiel: Funktionsdefinition
  double :: Int -> Int
  double n = 2*n

Die erste Zeile gibt die Typsignatur der Funktionen wieder. Sie definiert den Namen und den Typ der Funktion. Die Beispielfunktion "double" nimmt einen Integer als Input und gibt ein Integer als Ergebnis zurück.

Die zweite Zeile der Funktion stellt die eigentliche Definition dar, die wie eine mathematische Gleichung aufgebaut ist. Auf der rechten Seite des Gleichheitszeichens ist die Berechnung definiert.

Zur Definition von Funktionen bietet Haskell noch viele weitere hilfreiche Konstrukte wie das "Pattern Matching" oder die "Guards", um die Funktionen möglichst elegant zu designen.

Beispiel: Funktionsapplikation
  double 21
  -> 42

Bei der Ausführung einer Funktion oder der Funktionsapplikation wird die Definition Stück für Stück ausgewertet und das Ergebnis zurückgegeben. Bei der Auswertung wird lazy vorgegangen, d.h. in der Definition werden nur jene Ausdrücke ausgewertet, die auch für die Berechung eines Ergebnisses von Bedeutung ist.


2.3. Die Funktionskomposition

Ein weiteres wichtiges Merkmal von Haskell ist die Funktionskomposition. Mit ihr lassen sich wie in Unix mit den pipes, Funktionen verketten. In Haskell wird das mit dem Operator '.' erreicht. Kombiniert man zwei Funktionen g und h mit dem '.' Operator:

  g . h

bedeutet das, dass auf den Output von h die Funktion g angewendet wird. Voraussetzung für das Kombinieren von Funktionen ist der gleiche Typ jener Funktionen. Nur wenn das Resultat der einen Funktion mit dem Inputtyp der anderen Funktion übereinstimmt, lassen sie sich kombinieren. Diese Kette von Funktionen kann dann beliebig lang gestalltet werden. Man kann die Komposition auch so definieren:

  (g . h) x = g (h x)

2.4. Funktionen höherer Ordnung

Bei Funktionen höherer Ordnung spricht man von Funktionen, die als Argumente Funktionen aufnehmen und als Rückgabewert Funktionen zurückliefern. Ein Beispiel sind solche Funktionen, die die Funktionskomposition nutzen um neue Funktion zu erzeugen. Diese Funktionen werden auch Kombinatoren genannt.

Beispiel: Funktion höherer Ordnung
  map :: (a -> b) -> [a] -> [b]
  map f []     = [ ]
  map f (x:xs) = f x : map f xs

Mit der "map"-Funktion lässt sich jetzt eine Funktion erzeugen, die alle Elemente einer Liste mit zwei multipliziert:

Beispiel: doubleAll
  doubleAll xs = map double xs

[ Seminar "XML und Funktionale Programmierung" ] ... [ 1. Einführung ] ... [ 3. Datenstruktur ]