Einleitung Eq Klassen Vererbung Beispiele Einleitung Eq Klassen Vererbung Beispiele Gliederung Algorithmen und Datenstrukturen I 1 Einleitung Typklassen in Haskell 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 c Winter 2009/10, 23. November 2009, 2009/10 D.Rösner D. Rösner AuD I 2009/10 . . . D. Rösner AuD I 2009/10 . . . 1 Einleitung Eq Klassen Vererbung Beispiele 2 Einleitung Eq Klassen Vererbung Beispiele Qualifizierte Typen Qualifizierte Typen Beispiel: polymorphe Typen wie a -> a sind allquantifiziert m.a.W.: a -> a ist zu lesen als: 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 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 s.a. [Hud00], Ch. 12 D. Rösner AuD I 2009/10 . . . 3 D. Rösner AuD I 2009/10 . . . 4 Einleitung Eq Klassen Vererbung Beispiele Einleitung Eq Klassen Vererbung Beispiele Typklasse Eq Qualifizierte Typen Gleichheit zweier Ausdrücke e1 und e2 bedeutet in Haskell, dass der Wert von e1 und der Wert von e2 identisch sind Elemente einer Typklasse werden auch als Instanzen dieser Klasse bezeichnet alternative Sicht: wenn Gleichheit vorliegt, kann in einem Programm jedes Vorkommen von e1 durch e2 ersetzt werden, ohne das Programmresultat zu verändern Typklassen wie Num a sollten nicht verwechselt werden mit Datentypen oder Konstruktoren in einem Datentyp wie Tree a Gleichheit zweier Ausdrücke in diesem Sinne lässt sich im Allgemeinen nicht durch Programme bestimmen Beispiele: zusätzlich zu den vordefinierten Standard-Typklassen können auch Nutzer eigene Typklassen definieren Wann sind zwei unendliche Listen gleich? Wann sind zwei Funktionen vom Typ Integer -> Integer gleich? s.a. [Hud00], Ch. 12 D. Rösner AuD I 2009/10 . . . D. Rösner AuD I 2009/10 . . . 5 Einleitung Eq Klassen Vererbung Beispiele 6 Einleitung Eq Klassen Vererbung Beispiele Typklasse Eq Typklasse Eq man spricht von berechenbarer Gleichheit (engl. computational equality), wenn sich die Gleichheit zweier Werte tatsächlich ausrechnen lässt 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 die Klasse Eq enthält solche Typen, für die sich Gleichheit bestimmen lässt der Gleichheitsoperator hat dann den folgenden qualifizierten Typ (Integer, Char), [Integer], [Float] [(Integer, [Char])], ... (==) :: Eq a => a -> a -> Bool s.a. [Hud00], Ch. 12.1; [Tho99] D. Rösner AuD I 2009/10 . . . 7 D. Rösner AuD I 2009/10 . . . 8 Einleitung Eq Klassen Vererbung Beispiele Einleitung Eq Klassen Vererbung Beispiele Typklasse Eq Definition der Typklasse Eq Typbedingungen übertragen sich auch auf die Funktionen, in denen Operationen mit qualifiziertem Typ verwendet werden im Standard-Prelude findet sich eine Typklassen-Deklaration wie class Eq a where (==) :: a -> a -> Bool dies ist zu lesen als: Beispiel: elem :: Eq a => a -> [a] -> Bool ein Typ a ist nur dann eine Instanz der Klasse Eq, wenn für ihn eine Operation (==) :: a -> a -> Bool definiert ist eine gesetzte Signatur elem :: a -> [a] -> Bool wäre zu allgemein und würde zu Typfehler führen s.a. [Hud00], Ch. 12.2 s.a. [Hud00], Ch. 12.1 D. Rösner AuD I 2009/10 . . . 9 Einleitung Eq Klassen Vererbung Beispiele 10 Einleitung Eq Klassen Vererbung Beispiele Instanzen der Typklasse Eq Instanzen der Typklasse Eq auch eigendefinierte Datentypen können zu Instanzen von Eq gemacht werden Datentyp binärer Baum mit der folgenden Instanzdeklaration wird spezifiziert, dass Integer eine Instanz von Eq ist data Tree a = Leaf a | Branch (Tree a) (Tree a) instance Eq Integer where x == y = primEqInteger 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 die Definition von (==) wird Methode genannt eine analoge Methode erlaubt dann den Vergleich von Gleitkommazahlen mit (==) instance Eq a => Eq (Tree a) where Leaf a == Leaf b = a == b Branch l1 r1 == Branch l2 r2 = l1 == l2 && r1 == r2 _ == _ = False instance Eq Float where x == y = primEqFloat x y D. Rösner AuD I 2009/10 . . . D. Rösner AuD I 2009/10 . . . 11 D. Rösner AuD I 2009/10 . . . 12 Einleitung Eq Klassen Vererbung Beispiele Einleitung Eq Klassen Vererbung Beispiele Definition der Typklasse Eq Typklassen vs. Polymorphismus tatsächliche Definition von Eq im Standard-Prelude ist etwas umfangreicher und umfasst auch Test auf Ungleichheit Slogan: Polymorphism captures similar structure over different values, while type classes capture similar operations over different structures. class Eq a where (==),(/=) :: a -> a -> Bool x /= y = not (x == y) x == y = not (x /= y) 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. diese Methoden wirken als sog. Defaults (Voreinstellungswerte), falls eine Instanz nur eine der beiden Operationen definiert s.a. [Hud00], Ch. 12.2, p. 152 s.a. [Hud00], Ch. 12.2 D. Rösner AuD I 2009/10 . . . D. Rösner AuD I 2009/10 . . . 13 Einleitung Eq Klassen Vererbung Beispiele Einleitung Eq Klassen Vererbung Beispiele Vererbung bei Typklassen Vererbung bei Typklassen Motivation 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 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 instance Leaf _ Leaf a Branch Branch (<),(<=),(>=),(>) :: 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 . . . 14 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 15 D. Rösner AuD I 2009/10 . . . 16 Einleitung Eq Klassen Vererbung Beispiele Einleitung Eq Klassen Vererbung Beispiele Vererbung bei Typklassen 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 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 Beispiel (für multiple Vererbung) class (Eq a,Show a) => C a where ... generische Sortierfunktionen wie quicksort quicksort :: Ord a => [a] -> [a] s.a. [Hud00], Ch. 12.3 s.a. [Hud00], Ch. 12.3 D. Rösner AuD I 2009/10 . . . 17 Einleitung Eq Klassen Vererbung Beispiele D. Rösner AuD I 2009/10 . . . 18 Einleitung Eq Klassen Vererbung Beispiele Ableitung von Methoden 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 bestimmte Methoden in einer Klasse können automatisch abgeleitet werden vgl. Definition von Gleichheit für Bäume hierzu 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 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 D. Rösner AuD I 2009/10 . . . 20 Einleitung Eq Klassen Vererbung Beispiele Einleitung Eq Klassen Vererbung Beispiele Ord Enum Show, Read Weitere Typklassen Ableitung von Methoden vgl. Definition von Gleichheit für Bäume verbal: zur vollständigen Spezifikation von Ord gehört Beispiel Definition zwei Blätter sind genau dann gleich, wenn ihre Inhalte gleich sind class Eq a => Ord a where compare :: a -> a -> Ordering (<),(<=),(>=),(>) :: a -> a -> Bool max, min :: a -> a -> a 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 . . . Einleitung Eq Klassen Vererbung Beispiele s.a. [Tho99], Ch. 14; [Hud00], Ch. 24 D. Rösner AuD I 2009/10 . . . 21 Einleitung Eq Klassen Vererbung Beispiele Ord Enum Show, Read Ordungsklasse Ord 23 Ord Enum Show, Read Ordungsklasse Ord die Funktion compare ordnet zwei beliebigen Objekten gleichen Ordnungs-Typs einen der drei Werte aus Ordering zu der Datentyp Ordering Definition data Ordering = LT|EQ|GT deriving (Eq, Ord, Enum, Read, Show, Bounded) 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) Ordering enthält die drei möglichen Werte für Vergleiche zwischen zwei beliebigen Objekten gleichen Ordnungs-Typs: compare x y | x==y = EQ | x<=y = LT | otherwise = GT Kleiner-Beziehung: LT Gleichheit: EQ Grösser-Beziehung: GT D. Rösner AuD I 2009/10 . . . 24 D. Rösner AuD I 2009/10 . . . 25 Einleitung Eq Klassen Vererbung Beispiele Einleitung Eq Klassen Vererbung Beispiele Ord Enum Show, Read Ordungsklasse Ord Ord Enum Show, Read Weitere Typklassen umgekehrt ist die Default-Methode für (<=) (und weiterer Operatoren) definiert unter Verwendung von compare die Klasse Enum umfasst Methoden, die das Prinzip arithmetischer Sequenzen und die entsprechenden Kurzschreibweisen auf andere aufzählbare Typen übertragen Beispiel: 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 data Color = Red|Orange|Yellow|Green |Blue|Indigo|Violet 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 . . . Einleitung Eq Klassen Vererbung Beispiele D. Rösner AuD I 2009/10 . . . 26 Einleitung Eq Klassen Vererbung Beispiele Ord Enum Show, Read Enumeration 28 Ord Enum Show, Read Enumeration die Spezifikation von Enum (vgl. Prelude.hs): wird Color zur Instanz von Enum gemacht, dann (vgl. [Hud00], Ch. 24): class Enum a where succ, pred toEnum fromEnum enumFrom enumFromThen enumFromTo enumFromThenTo [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 :: :: :: :: :: :: :: 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 Einleitung Eq Klassen Vererbung Beispiele Ord Enum Show, Read Enumeration Ord Enum Show, Read Enumeration für die Deklaration eigener Instanzen sind diese vordefinierten Methoden normalerweise ausreichend es müssen lediglich definiert werden: 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 . . . Einleitung Eq Klassen Vererbung Beispiele 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) 31 D. Rösner AuD I 2009/10 . . . Einleitung Eq Klassen Vererbung Beispiele Ord Enum Show, Read Show, Read 32 Ord Enum Show, Read Show, Read Beispiele: Main> "GT" Main> GT Main> "Red" Main> Red 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 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 . . . 34 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