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 . . .