Andere Typen
Übersicht: Andere Typen
Typen, die auf anderen Typen basieren
Ein Beispiel für einen Datentypen, der auf anderen Typen basiert ist folgende, polymorphe Definition:
01 data Either a b = Left a | Right b
02 Left :: a -> Either a b
03 Right :: b -> Either a b
|
Die Funktionen Left
und Right
sind Konstruktoren für den Datentyp und sie
haben deshalb keine Definition. Die Namen Left
und Right
können auch als
Muster auf der linken Seite von Definitionen auftauchen.
Die Anzahl der Werte im Datentyp ergibt sich wie beim Paar aus der Anzahl der
Konstruktoren m für a
und der Anzahl der Konstruktoren n für b
.
Auch hier muss bei beiden Typen der undefinierte Wert einbezogen werden und der undefinierte Wert undefined
von Left undefined
und Right undefined
unterschieden werden.
Insgesamt ergeben sich also für den Datentyp 1 + (m + 1) + (n + 1) Werte.
Das folgende Beispiel kombiniert die Datentypen Bool
und Char
und besteht aus 261 Werten
(3 Bool'sche Werte, 257 Char Werte und undefined
).
01 data Either = Left Bool | Right Char
|
Andere Typen als Argumente in Funktionen
Die folgenden Definitionen der Funktionen case
und plus
verwenden die Eigenschaft,
dass die Konstruktoren auf der linken Seite von Definitionen auftauchen können. Das Wort plus kommt aus
der Kategorientheorie und wird dort durch die Notation f + g
bezeichnet.
01 case :: (a -> c,b -> c) -> Either a b -> c
02 case (f,g) (Left x) = f x
03 case (f,g) (Right x) = g x
04 plus :: (a -> b,c -> d) -> Either a b -> Either c d
05 plus (f,g) = case(Left . f,Right . g)
|
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. Man kann hier eine Parallele zu den Eigenschaften der Funktionen pair
und cross
feststellen, die der zugrundeliegende Algebra entspringt.
Die vierte Eigenschaft kann mit Hilfe der anderen Eigenschaften bewiesen
werden. Es wurde an dieser Stelle jedoch darauf verzichtet.
01 case (f,g) . Left = f
02 case (f,g) . Right = g
03 h . case (f,g) = case (h . f,h . g)
04 case (f,g) . plus (h,k) = case (f . h,g . k)
|
Gleichheits- und Ordnungsrelation für andere Typen
Für andere Typen können leicht Instanzen der Typklassen Eq
und Ord
gebildet
werden. Es gilt hier dieselbe Besonderheit wie bei der Definition bei Tupeln. Die einzelnen Typen, aus denen der
Datentyp besteht, müssen ebenfalls Instanzen der jeweiligen Typklasse sein. Die Instanzen können auch
automatisch mit Hilfe der deriving-Klausel erstellt werden.
01 instance (Eq a, Eq b) => Eq (Either a b) where
02 Left x == Left y = (x == y)
03 Left x == Right y = False
04 Right x == Left y = False
05 Right x == Right y = (x == y)
06
07 instance (Ord a, Ord b) => Ord (Either a b) where
08 Left x < Left y = (x < y)
09 Left x < Right y = False
10 Right x < Left y = False
11 Right x < Right y = (x < y)
|