Typklassen in Haskell - Universität Magdeburg

Werbung
Einleitung
Eq
Klassen
Vererbung
Beispiele
Einleitung
Eq
Klassen
Vererbung
Beispiele
Gliederung
Algorithmen und Datenstrukturen – Einführung
Typklassen in Haskell
1
Einleitung
2
Eq
3
Klassen
4
Vererbung
5
Beispiele
Ord
Enum
Show, Read
D. Rösner
Institut für Wissens- und Sprachverarbeitung
Fakultät für Informatik
Otto-von-Guericke Universität Magdeburg
Winter 2008/2009, 16. November 2008
D. Rösner
AuD 2008/2009 . . .
D. Rösner
Einleitung
Eq
Klassen
Vererbung
Beispiele
AuD 2008/2009 . . .
Einleitung
Eq
Klassen
Vererbung
Beispiele
Qualifizierte Typen
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
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
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
s.a. [Hud00], Ch. 12
D. Rösner
AuD 2008/2009 . . .
D. Rösner
AuD 2008/2009 . . .
Einleitung
Eq
Klassen
Vererbung
Beispiele
Einleitung
Eq
Klassen
Vererbung
Beispiele
Typklasse Eq
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
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]
AuD 2008/2009 . . .
D. Rösner
Einleitung
Eq
Klassen
Vererbung
Beispiele
AuD 2008/2009 . . .
Einleitung
Eq
Klassen
Vererbung
Beispiele
Typklasse Eq
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 die Typen
(Integer, Char),
[Integer],
[Float] usw.
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 2008/2009 . . .
D. Rösner
AuD 2008/2009 . . .
Einleitung
Eq
Klassen
Vererbung
Beispiele
Einleitung
Eq
Klassen
Vererbung
Beispiele
Definition der Typklasse Eq
Instanzen 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
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 (==)
s.a. [Hud00], Ch. 12.2
instance Eq Integer where
x == y = primEqFloat x y
D. Rösner
AuD 2008/2009 . . .
Einleitung
Eq
Klassen
Vererbung
Beispiele
D. Rösner
AuD 2008/2009 . . .
Einleitung
Eq
Klassen
Vererbung
Beispiele
Instanzen der Typklasse Eq
Definition der Typklasse Eq
auch eigendefinierte Datentypen können zu Instanzen von
Eq gemacht werden
Datentyp binärer Baum
tatsächliche Definition von Eq im Standard-Prelude ist
etwas umfangreicher und umfasst auch Test auf
Ungleichheit
data Tree a = Leaf a | Branch (Tree a) (Tree a)
class Eq a where
(==),(/=) :: a -> a-> Bool
x /= y
= not (x == y)
x == y
= not (x /= y)
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 2008/2009 . . .
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 2008/2009 . . .
Einleitung
Eq
Klassen
Vererbung
Beispiele
Einleitung
Eq
Klassen
Vererbung
Beispiele
Typklassen vs. Polymorphismus
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
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
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
AuD 2008/2009 . . .
D. Rösner
Einleitung
Eq
Klassen
Vererbung
Beispiele
Einleitung
Eq
Klassen
Vererbung
Beispiele
Vererbung bei Typklassen
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
AuD 2008/2009 . . .
True
a < b
False
l1 < l2 && r1 < r2
= t1 < t2 || t1 == t2
...
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
funktioniert in dieser Form, da Tree bereits Instanz von Eq
s.a. [Hud00], Ch. 12.3
D. Rösner
quicksort :: Ord a => [a] -> [a]
s.a. [Hud00], Ch. 12.3
AuD 2008/2009 . . .
D. Rösner
AuD 2008/2009 . . .
Einleitung
Eq
Klassen
Vererbung
Beispiele
Einleitung
Eq
Klassen
Vererbung
Beispiele
Vererbung bei Typklassen
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 ...
hierzu
Beispiel (für zusätzliche Klassenbedingungen)
class C a where
m :: Eq b => a -> b
s.a. [Hud00], Ch. 12.3
s.a. [Hud00], Ch. 12.3
D. Rösner
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
AuD 2008/2009 . . .
D. Rösner
Einleitung
Eq
Klassen
Vererbung
Beispiele
Einleitung
Eq
Klassen
Vererbung
Beispiele
Ableitung von Methoden
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 2008/2009 . . .
AuD 2008/2009 . . .
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 2008/2009 . . .
Einleitung
Eq
Klassen
Vererbung
Beispiele
Einleitung
Eq
Klassen
Vererbung
Beispiele
Ord
Enum
Show, Read
Weitere Typklassen
Ord
Enum
Show, Read
Ordungsklasse Ord
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
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
s.a. [Tho99], Ch. 14; [Hud00], Ch. 24
D. Rösner
AuD 2008/2009 . . .
D. Rösner
AuD 2008/2009 . . .
Einleitung
Eq
Klassen
Vererbung
Beispiele
Ord
Enum
Show, Read
Einleitung
Eq
Klassen
Vererbung
Beispiele
Ord
Enum
Show, Read
Ordungsklasse Ord
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
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
AuD 2008/2009 . . .
D. Rösner
AuD 2008/2009 . . .
Einleitung
Eq
Klassen
Vererbung
Beispiele
Einleitung
Eq
Klassen
Vererbung
Beispiele
Ord
Enum
Show, Read
Weitere Typklassen
Ord
Enum
Show, Read
Enumeration
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
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 ==> ...
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 2008/2009 . . .
D. Rösner
AuD 2008/2009 . . .
Einleitung
Eq
Klassen
Vererbung
Beispiele
Ord
Enum
Show, Read
Einleitung
Eq
Klassen
Vererbung
Beispiele
Ord
Enum
Show, Read
Enumeration
-----
[n..]
[n,m..]
[n..m]
[n,n’..m]
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 2008/2009 . . .
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 2008/2009 . . .
Einleitung
Eq
Klassen
Vererbung
Beispiele
Einleitung
Eq
Klassen
Vererbung
Beispiele
Ord
Enum
Show, Read
Show, Read
Ord
Enum
Show, Read
Show, Read
Beispiele:
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
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 2008/2009 . . .
Einleitung
Eq
Klassen
Vererbung
Beispiele
Ord
Enum
Show, Read
Literatur:
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 2008/2009 . . .
D. Rösner
AuD 2008/2009 . . .
Herunterladen