Funktionale Programmierung mit Haskell/ Datentypen im Eigenbau

SynonymeBearbeiten

Typensynonyme sind nichts weiter als ein anderer Name für schon vorhandene Typen. Das folgende Beispiel benennt ein Tupel aus zwei Double-Werten um in einen Typ namens Vector2D. Der Zugriff auf die einzelnen Komponenten der Vektoren in der Funktion addV, die zwei Vektoren addiert, funktioniert wie bei anderen 2-Tupeln auch mit den Funktionen fst und snd:

type Vector2D = (Double, Double)

addV :: Vector2D  -> Vector2D -> Vector2D
addV a b = (fst a + fst b, snd a + snd b)

Der Ergebnistyp ist dann ebenfalls vom Typ Vector2D, das stellt bereits die Typsignatur sicher:

  ghci t0.hs

Main> let a = addV (1, 2) (3, 2)
Main> a
(4.0,4.0)
Main> :type a
a :: Vector2D
Main>

AufzählungBearbeiten

Strukturierter TypBearbeiten

Typ mit newtypeBearbeiten

Typen kann man auch mit newtype erzeugen, dann hat man ähnlich wie bei data einen komplett neuen Typ. Dieser Typ, hier am Beispiel eines 2D-Punktes, kann eine Methode erben, mit der er sich zeigen kann:

newtype Punkt2D = P2D (Double, Double)
    deriving (Show)

getPX :: Punkt2D -> Double
getPX (P2D (a, b)) = a

getPY :: Punkt2D -> Double
getPY (P2D (a, b)) = b

deriving(Show) ist hierbei die Schreibweise dafür, dass der Compiler für unseren Typ eine geeignete Instanz der Typklasse Show herleiten soll, wodurch unser Typ anzeigbar wird:

  ghci t4.hs

Main> let p = P2D (1, 3)
Main> p
P2D (1.0,3.0)
Main> getPX p
1.0
Main> getPY p
3.0
Main>

Diese Anzeige können wir anpassen, indem wir den Typ Show so modifizieren, dass er mit unserem Typ Punkt2D zusammenarbeitet. Show können wir dann so verändern, wie wir es wollen. Die Typenklasse Show enthält unter anderem eine Methode namens show, die wir anpassen können:

newtype Punkt2D = P2D (Double, Double)

instance (Show Punkt2D) where
    show p = "Punkt2D Parameter: (" ++ show (getPX p) ++ ", " ++ show (getPY p) ++ ")"

getPX :: Punkt2D -> Double
getPX (P2D (a, b)) = a

getPY :: Punkt2D -> Double
getPY (P2D (a, b)) = b

Hier zeigen wir, wie sich die Änderung auswirkt:

  ghci t4.hs

Main> let p = P2D (1, 3)
Main> p
Punkt2D Parameter: (1.0, 3.0)
Main>

Parametrisierter TypBearbeiten

Typen selbst kann man parametrisieren. Unsere obige Definition von Punkt2D kann sowohl mit Double wie auch mit Integer einen Punkt ergeben.

newtype Vector2D d = V2D (d, d)

instance (Show a) => Show (Vector2D a) where
    show v = "Vector2D: Parameter: (" ++ show (getX v) ++ ", " ++ show (getY v) ++

getX :: Vector2D t -> t
getX (V2D (a, b)) = a

getY :: Vector2D t -> t
getY (V2D (a, b)) = b


  ghci t5.hs

Main> let v = V2D (1, 2)
Main> :type v
v :: Vector2D Integer
Main> v
Vector2D: Parameter: (1, 2)
Main>

AnmerkungenBearbeiten