home Funktionale Programmierung: Produkt- und Summen-Datentypen Prof. Dr. Uwe Schmidt FH Wedel

Produkt- und Summen-Datentypen

weiter

weiter

Produkt

Literatur
weiter
Paare
kartesisches Produkt: A×B
weiter
Definition
data Pair a b = MkPair a b
weiter
merke
polymorpher Datentyp
Datentyp mit Typparameter
weiter
merke
Pair besitzt genau einen Konstruktor
weiter
merke
Der Konstruktor ist eine Funktion mit 2 Parametern
 
MkPair :: a -> b -> Pair a b
weiter
Konvention
Konstruktoren beginnen immer mit einem Großbuchstaben
 
Konstruktoren dürfen in Mustern auftreten
weiter
Notation
vertrauter: Paar-Schreibweise (x, y)
 
(A, B)          -- der Wertebereich aller Paare
 
(x, y)          -- ein Paar
weiter
elementare Operationen
fst             :: (a, b) -> a
fst (x, y)      =  x
 
snd             :: (a, b) -> b
snd (x, y)      =  y
weiter
Werte

()
(, y)
(x, )
(x, y)
weiter
Anzahl Werte
data A  = A1 | A2 | ... | An
data B  = B1 | B2 | ... | Bm
 
type P  = (A, B)
weiter
?
Wieviele Werte besitzt P?
weiter
?
CPO für (Bool, Bool) ?
weiter
Beispiele
für Funktionen mit Paaren
 
pair            :: (a -> b, a -> c) -> a -> (b, c)
pair (f, g) x   =  (f x, g x)
 
cross           :: (a -> b, c -> d) -> (a, c) -> (b, d)
cross (f, g)    = pair (f . fst, g . snd)
weiter
cross
ist eine nichtstrikte Funktion
 
cross (f, g)  = (f , g )
weiter
Beweis
  cross (f,g)
={ definition cross }
  pair (f . fst, g . snd)
={ Definition pair }
  ((f .fst) , (g . snd) )
={ Definition . }
  (f (fst ), g (snd ))
={ Striktheit von fst, snd }
  (f , g )
weiter
Eigenschaften
Gesetzte
für cross und pair
 
fst . pair (f, g)          = f
snd . pair (f, g)          = g
 
pair (f, g) . h            = pair (f . h, g . h)
cross (f, g) . pair (h, k) = pair (f . h, g . k)
weiter
Beweis der letzten Gleichung
  cross (f, g) . pair (h, k)
={ definition cross }
  pair (f . fst, g . snd) . pair (h, k)
={ 3. Gleichung }
  pair (f . fst . pair (h, k), g . snd . pair (h, k))
={ 1. und 2. Gleichung }
  pair (f . h, g . k)
weiter
Vergleiche von Paaren
instance (Eq a, Eq b) => Eq (a, b) where
  (x, y) == (u, v)  =  (x == u) && (y == v)
 
instance (Ord a, Ord b) => Ord (a, b) where
  (x, y) < (u, v)   =  (x < u) || (x == u && y < v)
weiter
gegeben
(1, undefined) < (2, undefined) = ?
?
Resultat
gegeben
(undefined, 1) < (undefined, 2) = ?
(undefined, 1) < (3,         2) = ?
(3,         1) < (undefined, 2) = ?
?
Resultat
Operatoren
für pair und cross: mit Currying
 
(&&&)   :: (a -> b) -> (a -> c) -> a -> (b, c)
(&&&)   = curry pair
 
(***)   :: (a -> b) -> (c -> d) -> (a, c) -> (b, d)
(***)   = curry cross
 
-- definiert in Control.Arrow
weiter
?
Wie definiert man einen Datentyp für Tripel und Quadrupel?

weiter

Summe

Definition
Vereinigung zweier Datentypen
 
data Either a b = Left  a
                | Right b
weiter
merke
polymorpher Datentyp
merke
2 Konstruktor-Funktionen
 
Left    :: a -> Either a b
Right   :: b -> Either a b
weiter
Werte

Left 
Left x
Right 
Right y
weiter
Beispiel
für eigenen Summentyp mit eigenen Konstruktoren
 
data BoolOrChar = B Bool
                | C Char
weiter
?
Wieviele Werte besitzt BoolOrChar oder Either Bool Char ?
weiter
?
CPO für Either Bool Char ?
weiter
Funktionen
auf Either
 
either                  :: (a -> c) ->
                           (b -> c) ->
                           Either a b -> c
 
either f g (Left  x)    =  f x
either f g (Right y)    =  g y
 
plus                    :: (a -> c) ->
                           (b -> d) ->
                           Either a b -> Either c d
 
plus f g                = either (Left . f) (Right . g)
weiter
?
Punktweise Definition von plus?
weiter
Eigenschaften
Gesetze
für either und plus
 
either f g . Left     = f
either f g . Right    = g
h . either f g        = either (h . f) (h . g)
either f g . plus h k = either (f . h) (g . k)
weiter
merke
in Data.Either ist either vordefiniert
merke
Analogie zu den Eigenschaften von pair und cross?
weiter
Vergleiche
auf Summendatentypen
 
instance (Eq a, Eq b) => Eq (Either a b) where
  Left  x == Left  y  = (x == y)
  Left  x == Right y  = False
  Right x == Left  y  = False
  Right x == Right y  = (x == y)
 
instance (Ord a, Ord b) => Ord (Either a b) where
  Left  x <  Left  y  = (x < y)
  Left  x <  Right y  = True
  Right x <  Left  y  = False
  Right x <  Right y  = (x < y)
weiter
automatische Erzeugung
data Either a b = Left  a
                | Right b
                deriving (Eq, Ord)
weiter
?
Summendatentyp für drei Typen a, b, c?
weiter
Sonderfall
optionaler Datentyp: Entweder ein Wert oder Nichts
 
data Maybe a = Nothing
             | Just a
             deriving (Eq, Ord)
weiter
?
Anzahl Werte?
weiter
?
Analoge Funktionen zu either und plus?
weiter
maybe
analog zu either, nur mit Currying
vordefiniert
 
maybe :: c -> (b -> c) -> Maybe b -> c
maybe x f Nothing  = x
maybe x f (Just y) = f y
just
analog zu plus
 
just :: (b -> d) -> Maybe b -> Maybe d
just f Nothing  = Nothing
just f (Just x) = Just (f x)
 
just ist vordefiniert als fmap
Funktor
Maybe wird durch fmap zu einem Funktor
(Vorwärtsreferenz)

Letzte Änderung: 17.09.2017
© Prof. Dr. Uwe Schmidt
Prof. Dr. Uwe Schmidt FH Wedel