Tupel


... [ Seminar "Einführung in die funktionale Programmiersprache Haskell" ] ... [ Inhaltsverzeichnis ] ... [ zurück ] ... [ weiter ] ...

Übersicht: Tupel


Bedeutung und Definition von Tupeln


Durch die Definition von Tupeln kann man Werte miteinander kombinieren, so dass jede Kombination genau einen Wert des Datentyps bildet, durch den das Tupel definiert wurde. Die Bedeutung der Kombination ist das kartesische Produkt aus den dem Tupel zugrundeliegenden Typen.
Die häfigste Form eines Tupels ist das Paar. Es wird durch den polymorphen Typ (a,b) definiert. Hierbei können die Typen a und b beliebig und sogar identisch sein.
Ein Paar lässt sich in Haskell auch auf folgende Art definieren:

01  data Pair a b = MkPair a b
02  MkPair   :: a -> b -> Pair a b

MkPair ist eine Funktion mit der angegebenen Typdefinition. Da sie lediglich Elemente des Datentyps konstruiert wird keine Funktionsweise definiert.

Die Anzahl der Werte in einem allgemeinen Paar (a,b) ergibt sich aus der Anzahl der Konstruktoren m für a und der Anzahl der Konstruktoren n für b. Bei beiden Typen muss der undefinierte Wert einbezogen werden und der undefinierte Wert undefined unterscheidet sich voneinem Paar von undefinierten Werten:
(undefined,undefined) /= undefined
Insgesamt ergeben sich also für ein Paar 1 + (m + 1) * (n + 1) Werte.

Die erstgenannte Syntax kann in Haskell auch verwendet werden und entspricht dem traditionellen Ansatz. Ein Beispiel für eine Paar in dieser Syntax bestehend aus Integer und Bool:
(Integer,Bool)

Mit Hilfe von Haskell kann man viele verschiedene Formen von Tupeln definieren, angefangen mit den aufgezeigten Paaren über Tripel und Quadrupel bis hin zu n-Tupeln. Bei der Definition ist die Klammersetzung jedoch relevant. So sind folgende Tupel zu unterscheiden:

01  (a,(b,c))
02  ((a,b),c)
03  (a,b,c)

Die erste Zeile beschreibt ein Paar, dass als zweites Element wiederum ein Paar enthält. Im Gegensatz dazu beschreibt die zweite Zeile ein Paar, dessen erstes Element ein Paar ist. Die dritte Zeile dagegen zeigt ein Tripel.


[ nach oben ]

Einfache Funktionen für Tupel


Für Paare sind einfache Funktionen vordefiniert, mit denen sich die einzelnen Elemente des Paars wieder extrahieren lassen.

01  fst       ::  (a,b) -> a
02  fst (x,y)  =  x
03  snd       ::  (a,b) -> b
04  snd (x,y)  =  y


[ nach oben ]

Funktionen mit Paaren von Funktionen als Argument


Die folgenden Definitionen der Funktionen pair und cross verwenden die Eigenschaft, dass auch Paare von Funktionen gebildet werden können. Das Wort cross kommt aus der Kategorientheorie und wird dort durch die Notation f x g bezeichnet.

01  pair          ::  (a -> b,a -> c) -> a -> (b,c)
02  pair (f,g) x   =  (f x,g x)
03  cross         ::  (a -> b,c -> d) -> (a,c) -> (b,d)
04  cross (f,g)    =  pair(f . fst,g . snd)

Die Funktionen haben eine Reihe von Eigenschaften die im sogenannten "point-free"-Programmierstil ausgenutzt werden können. Diese Eigenschaften gelten allerdings nur für binäre Funktionen in der uncurried Schreibweise.
Die vierte Eigenschaft kann mit Hilfe der anderen Eigenschaften bewiesen werden. Es wurde an dieser Stelle jedoch darauf verzichtet.

01  fst . pair (f,g)          =  f
02  snd . pair (f,g)          =  g
03  pair (f,g) . h            =  pair (f . h,g . h)
04  cross (f,g) . pair (h,k)  =  pair(f . h,g . k)


[ nach oben ]

Nullary-Typ


Im Rahmen der Tupel existiert ein Nullary-Typ () mit den Werten () und undefined. Dieser Typ kann verwendet werden um Konstanten als Funktionen zu benutzen. Für die Konstante pi sieht die Funktionsdefinition beispielsweise folgendermassen aus:

01  pifun    :: () -> Float
02  pifun ()  = 3.14159

Konstanten zu Funktionen zu erheben macht vor allem im Kontext der Funktionskomposition Sinn. Hierdurch lässt sich die Konstante in Form einer Funktion durch eine weitere Funktionskomposition anwenden. Es kann dadurch die Klammersetzung und die Lesbarkeit der Programme verbessert werden.


[ nach oben ]

Gleichheits- und Ordnungsrelation für Tupel


Für Tupel können leicht Instanzen der Typklassen Eq und Ord gebildet werden. Eine Besonderheit bei der Definition ist hier zu beachten. Die einzelnen Typen, aus denen das Tupel besteht, müssen ebenfalls Instanzen der jeweiligen Typklasse sein.
Hier die Instanzdeklaration für ein Paar mit lexikografischer Ordnung:

01  instance (Eq a, Eq b) => Eq (a,b) where
02    (x,y) == (u,v)  =  (x == y) && (y == v)
03  
04  instance (Ord a, Ord b) => Ord (a,b) where
05    (x,y) <  (u,v)  =  (x < u) || (x == u && y < v)


... [ Seminar "Einführung in die funktionale Programmiersprache Haskell" ] ... [ Inhaltsverzeichnis ] ... [ zurück ] ... [ weiter ] ... [ nach oben ] ...