Algebraische Datentypen

Werbung
Funktionale Programmierung
ALP I
Funktionale Programmierung
Typ-Klassen
und
Algebraische Datentypen
SS 2011
Prof. Dr. Margarita Esponda
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Überladung von Datentypen
Funktionen sollen oft auf verschiedene Datentypen anwendbar
sein, aber nicht auf beliebige Datentypen.
Beispiel:
Die (+) Funktion oder die anderen arithmetischen Operationen
sollen auf die Datentypen Int und Double anwendbar sein, aber
nicht auf andere Datentypen.
1+2
2.5 + 3.4
Das wird gelöst, indem Typ-Klassen definiert werden.
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Typ-Klassen
Mit Typ-Klassen lassen sich in Haskell Typen zusammenfassen,
die ähnliche Operationen unterstützen.
Beispiel:
Variabler Datentyp
(+) :: Num a => a -> a -> a
Klassenname
Die Typ-Variable a kann alle Instanzen der Num-Typklasse
annehmen.
Die Funktion wird dann für alle Datentypen, die eine Instanz der NumKlasse sind, definiert.
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Definition von Typ-Klassen
Vordefinierte Typklassen:
Beispiel:
class
Eq a where
(==) :: a - > a -> Bool
instance Eq Int where
(==) = intEq
-- intEq ist die primitive Funktion, die zwei
-- ganze Zahlen auf Gleichheit testet.
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Definition von eigenen Typ-Klassen
Eine Typ-Klasse deklariert eine Familie von Funktionen,
die für verschiedene Typen unterschiedlich definiert sein
können.
Allgemeine Syntax:
class C a where
f1 :: t1
f2 :: t2
…
fn :: tn
Prof. Dr. Margarita Esponda
Typvariable
Die Typen ti müssen die
Typvariable a enthalten
Funktionale Programmierung
Typ-Klassen in Haskell
Eine Typ-Klasse ist eine Sammlung von Typen, auf
denen eine in der Typ-Klasse festgelegte Menge
von Funktionen definiert ist.
Die Typ-Klasse Num stellt z. B. die Sammlung der
numerischen Datentypen Int, Integer, Float,
Double usw. dar, auf denen die Funktionen
(+), (*), usw. definiert sind.
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Typklassen in Haskell
Die vordefinierte Num-Typ-Klasse sieht vereinfacht
so aus:
class Num a where
(+) :: a -> a
-> a
(-)
:: a -> a
-> a
(*)
:: a -> a -> a
negate :: a -> a
abs :: a -> a
signum :: a -> a
...
Typ-Klassen schreiben eine Schnittstelle vor.
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Typ-Klassen in Haskell
Alle Typen, die Instanzen von Ord sein sollen,
müssen die vorgeschriebenen Vergleichsoperationen
implementieren.
class Ord a where
(<)
:: a -> a
-> Bool
(<=)
:: a -> a
->
(>)
:: a -> a ->
Bool
(>=)
:: a -> a ->
Bool
max
:: a -> a -> a
min
:: a -> a -> a
…
Prof. Dr. Margarita Esponda
Bool
Funktionale Programmierung
Eigene Datentypen definieren
Typ-Synonyme
Ein vorhandener Datentyp wird umbenannt
Algebraische Datentypen
Neue Datentypen werden definiert mit Hilfe von
sogenannten Typ-Konstruktoren.
data
Prof. Dr. Margarita Esponda
Typ-Name = K1 | K2 | … | Kn
Funktionale Programmierung
Algebraische Datentypen
Allgemeine Form:
data
T a1 …ak =
K1 t11 … t1m
1
| K2 t21 … t2m
2
|…
| Kn tn1 … tnm
n
Die Ki sind Konstruktoren und die ai sind die TypParameter des neuen Datentyps T.
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Algebraische Datentypen
Beispiele:
einfache Aufzählungen
data Bool = True | False
data Move = Left | Right | Up | Down
type Position = (Int, Int)
Funktionsbeispiel:
move
move
move
move
move
Prof. Dr. Margarita Esponda
:: Move -> Position -> Position
Left (x,y) = (x-1,y)
Right (x,y) = (x+1,y)
Up
(x,y) = (x,y+1)
Down (x,y) = (x,y-1)
Funktionale Programmierung
Algebraische Datentypen
Beispiel:
data Weekday = Mo | Tu | We | Th | Fr | Sa | Su
isWeekend :: Weekday -> Bool
isWeekend Sa = True
isWeekend Su = True
isWeekend _ = False
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Beispiel:
Algebraische Datentypen
data Weekday = Mo | Tu | We | Th | Fr | Sa | Su
Mo == Mo
=> No instance for (Eq Weekday)
arising from a use of `==' at <interactive>:1:0-5
Possible fix: add an instance declaration for
(Eq Weekday)
Wir brauchen eine eigene
Gleichheits-Operation
1. Lösung
equal :: Weekday -> Weekday -> Bool
equal Mo Mo = True
equal Tu Tu = True
...
equal _ _ = False
instance Eq Weekday where
x == y = equal x y
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Beispiel:
Algebraische Datentypen
data Weekday = Mo | Tu | We | Th | Fr | Sa | Su
deriving (Eq, Ord, Show)
Instanzen dieser Klassen werden automatisch
aus der Typdefinition abgeleitet.
Eq
Gleichheit und Ungleichheit lässt sich durch Mustervergleich ableiten
Ord
verwendet die Reihenfolge der Konstruktoren in der Typdefinition
Mo < Tu < .. < Su
Show
Die Namen der Konstruktoren werden in Zeichenketten verwandelt
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Beispiel:
Algebraische Datentypen
data Weekday = Mo | Tu | We | Th | Fr | Sa | Su
deriving (Eq, Ord, Show, Enum)
Damit haben wir automatisch alle Vergleichsoperationen, eine
show-Funktion für die Ausgabe von Ausdrücken und AufzählungsFunktionen wie succ, pred, fromEnum usw.
Wir können sogar Listengeneratoren verwenden!
isWorkday :: Weekday -> Bool
isWorkday day = elem day [Mo .. Fr]
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Algebraische Datentypen
Typ-Konstruktoren mit Typen als Argumente
Beispiel:
data Temperatur = Celsius Double | Fahrenheit Double
| Kelvin Double
deriving Show
Die Show-Funktion wird abgeleitet
celsius2Kelvin :: Temperatur -> Temperatur
celsius2Kelvin (Celsius cel) = Kelvin (cel + 273.16)
fahrenheit2Celsius :: Temperatur -> Temperatur
fahrenheit2Celsius (Fahrenheit fah) = Celsius ((fah-32)*5/9)
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Algebraische Datentypen
type Point = (Double, Double)
data Shape = Circ Point Double | Rect Point Point | CPoly [Point]
deriving (Eq, Show)
area :: Shape-> Double
area (Circ _ d) = pi*d
area (Rect (x1, y1) (x2, y2)) = abs ((x2-x1) * (y2-y1))
area (CPoly ps) | length ps < 3 = 0
area (CPoly (p1:p2:p3:ps)) = triangleArea p1 p2 p3 +
area (CPoly (p1:p3:ps))
triangleArea :: Point -> Point -> Point
triangleArea (x1,y1) (x2,y2) (x3,y3) =
abs ((x2-x1)*(y3-y1) - (x3-x1)*(y2-y1)) / 2
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Algebraische Datentypen
Rekursive Definitionen
Beispiel:
data Tree = Leaf Int | Node Int Tree Tree | Nil
53
27
13
69
34
63
46
Prof. Dr. Margarita Esponda
95
Herunterladen