Klassen
Klassen
sind in Haskell Typklassen, dh Kollektionen von Typen, die durch einen gemeinsamen Satz von Operationen ausgezeichnet sind.
Idee aus der OO-Welt, aber in Haskell:
- sowieso keine Objekte (mit änderbarem Zustand), sondern nur Werte
- nicht dynamische ("`runtime"') Bindung einer Funktion, sondern Typüberprüfung zur compile-time
- viele OO-Sprachen verwenden "`Klasse"' wie "`Typ"', in Ada ähnlich wie in Haskell:
"`Klasse"' = Familie von Typen, nämlich Definitionshierarchie
- Klassendefinitionen in Haskell sind normalerweise abstrakt (nur Interfaces, allerdings defaults für Funktionen möglich) und enthalten jedenfalls keine "`Daten"'-Definitionen
-
Klassen können haben
- "`instances"' (Exemplare), dh Typen, die zur Klasse gehören
- "`subclasses"' (abgeleitete Klassen), dh Klassen, die die Operationen der Oberklassse "`erben"'.
instance = Typ subclass = class, dh Menge von Typen
- es gibt Sortiment von vordefinierten Klassen wie zB Eq, Ord, Num, Show, Read u.a., die man typisch verwendet um
- 1.
- bei überladenen Funktionen den Polymorphismus sinnvoll einzuschränken, dh die zulässige Auswahl von Typen anzugeben, zB:
quicksort :: Ord a => [a]->[a]
\--/
Kontextklausel: a muß Instanz von Ord sein (mittelbar)
- 2.
- bei der Neueinführung von Datentypen eine "`Grundausstattung"' mit Operationen herzustellen, zB: Datentyp zur Instanz von "`Eq"' machen.
- zu vordefinierten Klassen siehe Report, zB:
class Eq a
where (==), (/=) :: a->a->Bool
x/=y = not (x==y) - dh default für /=
Beispiel für Unterklasse von Eq ist Ord, die zu ``=='' noch die Operationen ``<, <=, >=, >'' sowie die Funktionen ``min, max'' (und noch eine Funktion ``compare'' die ein symbolisches Ergebnis liefert) definiert.
Beispiel von Instanzen von Eq gibt's massenhaft, zB Int.
Beispiel: benutzerdefinierter Datentyp als Instanz von Eq:
-------------------old defs do not support "=":
data PrimaryColour = Yellow | Red | Blue
--------------------------as is shown by:
{-
Main> Yellow == Blue
ERROR: PrimaryColour is not an instance of class "Eq"
-}
-------------so make new type an instance of class Eq:
data PrimaryColour = Yellow | Red | Blue
instance Eq PrimaryColour
where Yellow == Yellow = True
Red == Red = True
Blue == Blue = True
_ == _ = True
---------------------------which allows:
{-
Main> Yellow == Blue
False
-}
-------------------this can be done more simply:
data PrimaryColour = Yellow | Red | Blue deriving Eq
-----------------------which gives the same:
{-
Main> Yellow == Blue
False
Main> Yellow /= Blue
True
-}
-----but other defs of "==" could be useful for colour blinds:
data PrimaryColour = Yellow | Red | Blue
instance Eq PrimaryColour
where _ == _ = True
------------------------------giving:
{-
Main> Yellow == Blue
True
-}
Beispiel: Definition einer Klasse und zweier Instanzen
-------------------now define your own classes:
class Mail m
where giveAdr:: m->String
setAdr:: String->m->m
existsAdr:: m->Bool
existsAdr x = (giveAdr x /= "") - default
data SimpleLetter a = SL String a - hat eine Adresse
instance Mail (SimpleLetter a)
where giveAdr (SL s _) = s
setAdr s (SL s' x) = (SL s x)
data BroadcastLetter a = BC [String] a - hat Liste von Adressen
clearAdr:: (BroadcastLetter a)->(BroadcastLetter a)
clearAdr (BC ss x) = BC [] x
instance Mail (BroadcastLetter a)
where giveAdr (BC [] _) = ""
giveAdr (BC (s:ss) _) = s
setAdr s (BC ss x) = BC (s:ss) x
-----------------------------examples:
{-
Main> existsAdr (SL "Grete" (25, "Now", 1997))
True
Main> giveAdr(setAdr "Gustav" (setAdr "Franz"
(SL "Grete" (25, "Nov", 1997))))
"Gustav"
Main> giveAdr (clearAdr (BC ["Grete"] (25, "Nov", 1997)))
""
Main> existsAdr (clearAdr (BC ["Grete"] (25, "Nov", 1997)))
False
-}
Next:ÜbungenUp:Benutzerdefinierte Datentypen und TypklassenPrevious:Abstrakte Datentypen Ronald Blaschke
1998-04-19