Typklassen in Haskell - Otto-von-Guericke

Werbung
Einleitung
Eq
Klassen
Vererbung
Beispiele
Algorithmen und Datenstrukturen I
Typklassen in Haskell
D. Rösner
Institut für Wissens- und Sprachverarbeitung
Fakultät für Informatik
Otto-von-Guericke Universität Magdeburg
c
Winter 2009/10, 23. November 2009, 2009/10
D.Rösner
D. Rösner AuD I 2009/10 . . .
1
Einleitung
Eq
Klassen
Vererbung
Beispiele
Gliederung
1
Einleitung
2
Eq
3
Klassen
4
Vererbung
5
Beispiele
Ord
Enum
Show, Read
D. Rösner AuD I 2009/10 . . .
2
Einleitung
Eq
Klassen
Vererbung
Beispiele
Qualifizierte Typen
polymorphe Typen wie a -> a sind allquantifiziert
m.a.W.: a -> a ist zu lesen als:
für alle Typen a, eine Funktion, die Elemente vom Typ a auf
Elemente vom Typ a abbildet
qualifizierte Typen erlauben, die Quantifizierung auf eine
Klasse von Typen einzuschränken
s.a. [Hud00], Ch. 12
D. Rösner AuD I 2009/10 . . .
3
Einleitung
Eq
Klassen
Vererbung
Beispiele
Qualifizierte Typen
Beispiel:
zur Klasse Num gehören u.a. die Typen Integer, Float,
Complex
mit
(+) :: Num a => a -> a -> a
wird dann ausgedrückt:
für alle Typen a, die zur Klasse Num gehören, hat (+)
den Typ a -> a -> a
s.a. [Hud00], Ch. 12
D. Rösner AuD I 2009/10 . . .
4
Einleitung
Eq
Klassen
Vererbung
Beispiele
Qualifizierte Typen
Elemente einer Typklasse werden auch als Instanzen
dieser Klasse bezeichnet
Typklassen wie Num a sollten nicht verwechselt werden
mit Datentypen oder Konstruktoren in einem Datentyp wie
Tree a
zusätzlich zu den vordefinierten Standard-Typklassen
können auch Nutzer eigene Typklassen definieren
s.a. [Hud00], Ch. 12
D. Rösner AuD I 2009/10 . . .
5
Einleitung
Eq
Klassen
Vererbung
Beispiele
Typklasse Eq
Gleichheit zweier Ausdrücke e1 und e2 bedeutet in Haskell,
dass der Wert von e1 und der Wert von e2 identisch sind
alternative Sicht: wenn Gleichheit vorliegt, kann in einem
Programm jedes Vorkommen von e1 durch e2 ersetzt
werden, ohne das Programmresultat zu verändern
Gleichheit zweier Ausdrücke in diesem Sinne lässt sich im
Allgemeinen nicht durch Programme bestimmen
Beispiele:
Wann sind zwei unendliche Listen gleich?
Wann sind zwei Funktionen vom Typ
Integer -> Integer gleich?
D. Rösner AuD I 2009/10 . . .
6
Einleitung
Eq
Klassen
Vererbung
Beispiele
Typklasse Eq
man spricht von berechenbarer Gleichheit (engl.
computational equality), wenn sich die Gleichheit zweier
Werte tatsächlich ausrechnen lässt
die Klasse Eq enthält solche Typen, für die sich Gleichheit
bestimmen lässt
der Gleichheitsoperator hat dann den folgenden
qualifizierten Typ
(==) :: Eq a => a -> a -> Bool
s.a. [Hud00], Ch. 12.1; [Tho99]
D. Rösner AuD I 2009/10 . . .
7
Einleitung
Eq
Klassen
Vererbung
Beispiele
Typklasse Eq
die Bedingungen qualifizierter Typen (die sog. type
constraints) übertragen sich auf polymorphe Datentypen
m.a.W. da Integer, Char, Float Instanzen von Eq sind ,
sind es auch aggregierte Typen
(Integer, Char),
[Integer],
[Float]
[(Integer, [Char])],
...
D. Rösner AuD I 2009/10 . . .
8
Einleitung
Eq
Klassen
Vererbung
Beispiele
Typklasse Eq
Typbedingungen übertragen sich auch auf die Funktionen,
in denen Operationen mit qualifiziertem Typ verwendet
werden
Beispiel:
elem :: Eq a => a -> [a] -> Bool
eine gesetzte Signatur
elem :: a -> [a] -> Bool
wäre zu allgemein und würde zu Typfehler führen
s.a. [Hud00], Ch. 12.1
D. Rösner AuD I 2009/10 . . .
9
Einleitung
Eq
Klassen
Vererbung
Beispiele
Definition der Typklasse Eq
im Standard-Prelude findet sich eine
Typklassen-Deklaration wie
class Eq a where
(==) :: a -> a -> Bool
dies ist zu lesen als:
ein Typ a ist nur dann eine Instanz der Klasse Eq, wenn für
ihn eine Operation (==) :: a -> a -> Bool definiert
ist
s.a. [Hud00], Ch. 12.2
D. Rösner AuD I 2009/10 . . .
10
Einleitung
Eq
Klassen
Vererbung
Beispiele
Instanzen der Typklasse Eq
mit der folgenden Instanzdeklaration wird spezifiziert, dass
Integer eine Instanz von Eq ist
instance Eq Integer where
x == y = primEqInteger x y
die Definition von (==) wird Methode genannt
eine analoge Methode erlaubt dann den Vergleich von
Gleitkommazahlen mit (==)
instance Eq Float where
x == y = primEqFloat x y
D. Rösner AuD I 2009/10 . . .
11
Einleitung
Eq
Klassen
Vererbung
Beispiele
Instanzen der Typklasse Eq
auch eigendefinierte Datentypen können zu Instanzen von
Eq gemacht werden
Datentyp binärer Baum
data Tree a = Leaf a | Branch (Tree a) (Tree a)
damit Blätter des Baumes verglichen werden können,
muss der Typ der im Baum gespeicherten Werte aus Eq
sein
Bedingung in der Instanzdeklaration
instance Eq a => Eq (Tree a) where
Leaf a == Leaf b
= a == b
Branch l1 r1 == Branch l2 r2
= l1 == l2 && r1 == r2
_ == _
= False
D. Rösner AuD I 2009/10 . . .
12
Einleitung
Eq
Klassen
Vererbung
Beispiele
Definition der Typklasse Eq
tatsächliche Definition von Eq im Standard-Prelude ist
etwas umfangreicher und umfasst auch Test auf
Ungleichheit
class Eq a where
(==),(/=) :: a -> a -> Bool
x /= y
= not (x == y)
x == y
= not (x /= y)
diese Methoden wirken als sog. Defaults
(Voreinstellungswerte), falls eine Instanz nur eine der
beiden Operationen definiert
s.a. [Hud00], Ch. 12.2
D. Rösner AuD I 2009/10 . . .
13
Einleitung
Eq
Klassen
Vererbung
Beispiele
Typklassen vs. Polymorphismus
Slogan:
Polymorphism captures similar structure over different
values,
while type classes capture similar operations over different
structures.
also:
polymorphes List für Sequenzen von ganzen Zahlen, für
Sequenzen von Zeichen, usw.
Typklasse Eq, um Test auf Gleichheit bereitzustellen für
ganze Zahlen, für Bäume, usw.
s.a. [Hud00], Ch. 12.2, p. 152
D. Rösner AuD I 2009/10 . . .
14
Einleitung
Eq
Klassen
Vererbung
Beispiele
Vererbung bei Typklassen
Motivation
Wunsch nach Klasse Ord, welche die Operationen von Eq
erbt, aber zusätzlich Vergleichsoperationen und Funktionen
für Minimum und Maximum besitzt
mögliche Definition (vereinfacht, s.a. Prelude.hs):
class Eq a => Ord a where
(<),(<=),(>=),(>) :: a -> a -> Bool
max, min
:: a -> a -> a
Sprechweise: Eq ist Superklasse von Ord bzw. Ord ist
Subklasse von Eq (auch: Oberklasse bzw. Unterklasse)
jeder Typ, der Instanz von Ord, muss auch Instanz von Eq
sein
s.a. [Hud00], Ch. 12.3
D. Rösner AuD I 2009/10 . . .
15
Einleitung
Eq
Klassen
Vererbung
Beispiele
Vererbung bei Typklassen
mit folgender Instanzdeklaration wird der Datentyp für
Bäume (also Tree a) zu Instanz von Ord für solche
Elementtypen a, die selbst zu Ord gehören
instance
Leaf _
Leaf a
Branch
Branch
Ord a => Ord (Tree a) where
< Branch _ _
=
< Leaf b
=
_ _ < Leaf _
=
l1 r1 < Branch l2 r2
=
t1 <= t2
True
a < b
False
l1 < l2 && r1 < r2
= t1 < t2 || t1 == t2
...
funktioniert in dieser Form, da Tree bereits Instanz von Eq
s.a. [Hud00], Ch. 12.3
D. Rösner AuD I 2009/10 . . .
16
Einleitung
Eq
Klassen
Vererbung
Beispiele
Vererbung bei Typklassen
aufgrund der Vererbung zwischen Typklassen können
Typbedingungen in Signaturen von Funktionen kompakter
formuliert werden
Beispiel: bei einer Funktion, die Operationen sowohl aus
Eq, als auch aus Ord verwendet, reicht in der Signatur die
Bedingung Ord a statt (Eq a,Ord a)
hierzu
Beispiel
generische Sortierfunktionen wie quicksort
quicksort :: Ord a => [a] -> [a]
s.a. [Hud00], Ch. 12.3
D. Rösner AuD I 2009/10 . . .
17
Einleitung
Eq
Klassen
Vererbung
Beispiele
Vererbung bei Typklassen
multiple Vererbung (Mehrfachvererbung) von Operationen
aus mehreren Typklassen ist möglich
Namenskonflikte werden durch die Bedingung
ausgeschlossen, dass eine bestimmte Operation in jedem
beliebigen Skopus nur Element in höchstens einer Klasse
sein kann
also:
Beispiel (für multiple Vererbung)
class (Eq a,Show a) => C a where ...
s.a. [Hud00], Ch. 12.3
D. Rösner AuD I 2009/10 . . .
18
Einleitung
Eq
Klassen
Vererbung
Beispiele
Vererbung bei Typklassen
Methoden in einer Klasse können zusätzliche
Klassenbedingungen für jede beliebige verwendete
Typvariable haben, ausgenommen für die Variable, die in
der zu definierenden Klasse selbst verwendet wird
hierzu
Beispiel (für zusätzliche Klassenbedingungen)
class C a where
m :: Eq b => a -> b
s.a. [Hud00], Ch. 12.3
D. Rösner AuD I 2009/10 . . .
19
Einleitung
Eq
Klassen
Vererbung
Beispiele
Ableitung von Methoden
bestimmte Methoden in einer Klasse können automatisch
abgeleitet werden
vgl. Definition von Gleichheit für Bäume
Beispiel (für kanonische Definition von Gleichheit)
instance Eq a => Eq (Tree a) where
Leaf a == Leaf b = a == b
Branch l1 r1 == Branch l2 r2
= l1 == l2 && r1 == r2
_ == _
= False
D. Rösner AuD I 2009/10 . . .
20
Einleitung
Eq
Klassen
Vererbung
Beispiele
Ableitung von Methoden
vgl. Definition von Gleichheit für Bäume
verbal:
Beispiel
zwei Blätter sind genau dann gleich, wenn ihre Inhalte gleich
sind
zwei Verzweigungen sind genau dann gleich, wenn ihre linken
und rechten Teilbäume jeweils gleich sind
in allen anderen Fällen sind zwei Bäume ungleich
eine solche kanonische Definition von Gleichheit lässt sich
automatisch auf andere definierte Datentypen übertragen
s.a. [Hud00], Ch. 12.5
D. Rösner AuD I 2009/10 . . .
21
Einleitung
Eq
Klassen
Vererbung
Beispiele
Ord
Enum
Show, Read
Weitere Typklassen
zur vollständigen Spezifikation von Ord gehört
Definition
class Eq a => Ord a where
compare
:: a -> a -> Ordering
(<),(<=),(>=),(>) :: a -> a -> Bool
max, min
:: a -> a -> a
s.a. [Tho99], Ch. 14; [Hud00], Ch. 24
D. Rösner AuD I 2009/10 . . .
23
Einleitung
Eq
Klassen
Vererbung
Beispiele
Ord
Enum
Show, Read
Ordungsklasse Ord
der Datentyp Ordering
Definition
data Ordering
= LT|EQ|GT
deriving (Eq, Ord, Enum, Read, Show, Bounded)
Ordering enthält die drei möglichen Werte für Vergleiche
zwischen zwei beliebigen Objekten gleichen
Ordnungs-Typs:
Kleiner-Beziehung: LT
Gleichheit: EQ
Grösser-Beziehung: GT
D. Rösner AuD I 2009/10 . . .
24
Einleitung
Eq
Klassen
Vererbung
Beispiele
Ord
Enum
Show, Read
Ordungsklasse Ord
die Funktion compare ordnet zwei beliebigen Objekten
gleichen Ordnungs-Typs einen der drei Werte aus
Ordering zu
die Default-Definition in Klasse Ord benutzt den Operator
(<=) aus Ord und den Operator (==) aus Eq
Definition (aus Spezifikation von Klasse Ord in Prelude.hs)
compare x y
| x==y
= EQ
| x<=y
= LT
| otherwise = GT
D. Rösner AuD I 2009/10 . . .
25
Einleitung
Eq
Klassen
Vererbung
Beispiele
Ord
Enum
Show, Read
Ordungsklasse Ord
umgekehrt ist die Default-Methode für (<=) (und weiterer
Operatoren) definiert unter Verwendung von compare
Definition (aus Spezifikation von Klasse Ord in Prelude.hs)
x
x
x
x
<=
<
>=
>
y
y
y
y
=
=
=
=
compare
compare
compare
compare
x
x
x
x
y
y
y
y
/=
==
/=
==
GT
LT
LT
GT
Konsequenz: eine Instanz von Ord sollte zumindest eine
eigene Definition für den Operator (<=) oder für die
Funktion compare besitzen, um wohldefiniert zu sein
D. Rösner AuD I 2009/10 . . .
26
Einleitung
Eq
Klassen
Vererbung
Beispiele
Ord
Enum
Show, Read
Weitere Typklassen
die Klasse Enum umfasst Methoden, die das Prinzip
arithmetischer Sequenzen und die entsprechenden
Kurzschreibweisen auf andere aufzählbare Typen
übertragen
Beispiel:
data Color = Red|Orange|Yellow|Green
|Blue|Indigo|Violet
D. Rösner AuD I 2009/10 . . .
28
Einleitung
Eq
Klassen
Vererbung
Beispiele
Ord
Enum
Show, Read
Enumeration
wird Color zur Instanz von Enum gemacht, dann (vgl.
[Hud00], Ch. 24):
[Red .. Violet]
==> [Red,Orange,Yellow,Green,Blue,Indigo,Violet]
[Red,Yellow ..]
==> ...
fromEnum Green ==> 3
toEnum 5::Color ==> ...
D. Rösner AuD I 2009/10 . . .
29
Einleitung
Eq
Klassen
Vererbung
Beispiele
Ord
Enum
Show, Read
Enumeration
die Spezifikation von Enum (vgl. Prelude.hs):
class Enum a where
succ, pred
toEnum
fromEnum
enumFrom
enumFromThen
enumFromTo
enumFromThenTo
::
::
::
::
::
::
::
a -> a
Int -> a
a -> Int
a -> [a]
a -> a -> [a]
a -> a -> [a]
a -> a -> a -> [a]
D. Rösner AuD I 2009/10 . . .
-----
[n..]
[n,m..]
[n..m]
[n,n’..m]
30
Einleitung
Eq
Klassen
Vererbung
Beispiele
Ord
Enum
Show, Read
Enumeration
Default-Methoden von Enum (vgl. Prelude.hs):
-- Minimal complete definition: toEnum, fromEnum
succ
= toEnum . (1+)
. fromEnum
pred
= toEnum . subtract 1 . fromEnum
enumFrom x
= map toEnum [fromEnum x ..]
enumFromThen x y = map toEnum [fromEnum x,fromEnum y ..]
enumFromTo x y
= map toEnum [fromEnum x .. fromEnum y]
enumFromThenTo x y z
= map toEnum [fromEnum x,fromEnum y .. fromEnum z]
D. Rösner AuD I 2009/10 . . .
31
Einleitung
Eq
Klassen
Vererbung
Beispiele
Ord
Enum
Show, Read
Enumeration
für die Deklaration eigener Instanzen sind diese
vordefinierten Methoden normalerweise ausreichend
es müssen lediglich definiert werden:
toEnum
fromEnum
für Aufzählungstypen kann man sich auch völlig auf
Ableitung durch eine entsprechende deriving-Klausel
stützen
Beispiel:
data Color = Red|Orange|Yellow|Green
|Blue|Indigo|Violet
deriving (Eq, Ord, Enum, Show, Read)
D. Rösner AuD I 2009/10 . . .
32
Einleitung
Eq
Klassen
Vererbung
Beispiele
Ord
Enum
Show, Read
Show, Read
mit der Methode show aus der Typklasse Show wird einem
Datenobjekt aus einer Instanz von Show ein String (eine
sog. textuelle Repräsentation) zugeordnet
mit der Methode read aus der Typklasse Read wird eine
textuelle Repräsentation (ein String) geparst und daraus
ein Datenobjekt einer Instanz von Read gewonnen
D. Rösner AuD I 2009/10 . . .
34
Einleitung
Eq
Klassen
Vererbung
Beispiele
Ord
Enum
Show, Read
Show, Read
Beispiele:
Main>
"GT"
Main>
GT
Main>
"Red"
Main>
Red
show GT
read "GT"::Ordering
show Red
read "Red"::Color
Beachte: Umgang mit Strings
Main> read "\"Red\""::String
"Red"
Main> show "Red"
"\"Red\""
D. Rösner AuD I 2009/10 . . .
35
Einleitung
Eq
Klassen
Vererbung
Beispiele
Ord
Enum
Show, Read
Literatur: I
Paul Hudak.
The Haskell School of Expression – Learning Functional
Programming through Multimedia.
Cambridge University Press, Cambridge, UK, 2000.
ISBN 0-521-64338-4.
Simon Thompson.
Haskell - The Craft of Functional Programming.
Addison Wesley Longman Ltd., Essex, 1999.
2nd edition, ISBN 0-201-34275-8; Accompanying Web site:
http://www.cs.ukc.ac.uk/people/staff/sjt/craft2e.
D. Rösner AuD I 2009/10 . . .
36
Herunterladen