ALP I Abstrakte Datentypen WS 2009/2010 Prof. Dr. Margarita Esponda Prof. Dr. Margarita Esponda 1 Haskell Typsystem Monomorphe Funktionen Der Datentyp wird genau durch die Signatur bestimmt Beispiel: asciiCode :: Char -> Bool Polymorphe Funktionen Typvariablen in der Signatur lassen beliebige Datentypen zu Beispiel: length :: [a] -> [a] Prof. Dr. Margarita Esponda 2 Einschränkung von Typen Mit Hilfe von vordefinierten Typklassen können polymorphe Funktionen mit Einschränkung definiert werden Verwendung eines Kontextes Beispiel: equalList:: Eq a => [a]->[a] nur für Datentypen mit Vergleichsoperation add2List:: Num a => [a] -> a -> [a] add2List xs y = map (+y) xs nur numerische Typen mit definierten arithmetischen Operationen Prof. Dr. Margarita Esponda 3 Einige vordefinierte Typklassen Prof. Dr. Margarita Esponda 4 Typ--Anpassung Typ In Haskell ist Typ-Anpassung für numerische Werte wie in anderen Programmiersprachen nicht erlaubt. Beispiel: mod 3 2 + 1.5 Fehler: <interactive>:1:10: Ambiguous type variable `t' in the constraints: `Fractional t' arising from the literal `1.5' at <interactive>:1:10-12 `Integral t' arising from a use of `mod' at <interactive>:1:0-6 Probable fix: add a type signature that fixes these type variable(s) Explizites Type-Casting muss statt finden fromIntegral (mod 3 2) + 1.5 Prof. Dr. Margarita Esponda 5 Typklassen Typen werden durch die Operationen, die auf ihren Werten definiert werden sollen, beschrieben. Beispiel: Class Num a where Typklassen sind abstrakte (+) :: a -> a -> a Schnittstellen, weil keine (*) :: a -> a -> a Implementierung vorgegeben (-) :: a -> a -> a wird. Prof. Dr. Margarita Esponda 6 Instanzen von Typklassen Mit einer Instanz-Deklaration definieren wir, welche Typen zu welchen Typklassen gehören. Vordefinierte primitive Funktionen instance Num Int where x+y = primAdd x y neg x = primNegateInt x ... instance Eq Char where x == y = ord c == ord d Prof. Dr. Margarita Esponda 7 Instanzen von Typklassen Der Instanz-Typ einer Klasse muss die vorgeschriebenen Operationen einer Typklasse implementieren. Implementierung: instance (Eq a) => Eq [a] where (==) [] [] = True (==) [] (x:xs) = False (==) (x:ys) [] = False (==) (x:xs) (y:ys) = x == y && xs == ys Prof. Dr. Margarita Esponda 8 Instanzen von Typklassen data Menge a = Set [a] instance Eq a => Eq (Menge a) where Set xs == Set ys = subset xs ys && subset ys xs subset :: Eq a => a -> a -> a subset xs ys = all (’elem’ ys) xs instance (Ord a) => Ord (Menge a) where Set xs <= Set ys = subset xs ys Prof. Dr. Margarita Esponda 9 Subklassen Klassen dürfen andere Klassen umfassen class (Eq a, Show a) => Num a where (+), (-), (*) :: a -> a -> a negate :: a -> a abs, signum :: a -> a fromInteger :: Integer -> a -- Minimal complete definition: -- All, except negate or (-) x - y = x + negate y -- Default-Definitionen negate x = 0 - x Prof. Dr. Margarita Esponda 10 Mehrere Oberklassen class Enum a where class Num a where fromEnum :: a -> Int (+) :: a -> a -> a toEnum neg :: a -> a :: Int -> a ... ... Integral erbt die Operationen von Enum und Num, und fügt class (Enum a, Num a) => Integral a where quot, rem, div, mod :: a -> a -> a quotRem, divMod even, odd :: a -> a -> (a,a) :: a -> Bool toInteger :: a -> Integer toInt :: a -> Int Prof. Dr. Margarita Esponda noch weitere Operationen hinzu. Ausprägungen von Integral müssen folglich auch Ausprägungen von Enum und Num sein. 11 TypklassenHierarchie Prof. Dr. Margarita Esponda 12 Beispiel data List a = List [a] deriving Show class Collection c where add :: c a -> a -> c a remove :: (Eq a) => c a -> a -> c a construct :: [a] -> c a instance Collection List where add (List list) elem = List (list ++ [elem]) remove (List list) elem = List (aux list elem) where aux [] elem = [] aux (x : xs) elem | x == elem = xs |otherwise = x : (aux xs elem) construct xs = List xs Prof. Dr. Margarita Esponda 13 Abstrakte Datentypen Konkrete Datentypen • konkrete Darstellung der Information innerhalb einer Sprache • Listen, Bäume usw. Datentypen Abstrakte Datentypen • definiert durch die Operationen • unabhängig von einer konkreten Darstellung des Datentyps. Prof. Dr. Margarita Esponda 14 Abstrakte Datentypen • sind Datentypen, die durch die auf ihren Werten erlaubten Operationen definiert sind, und dessen Implementierung den Nutzern des Typs verborgen (Datenkapselung) ist • die Implementierung des Datentyps kann verändert werden, ohne dass sich der Code, der diesen Datentyp verwendet, ändern muss • in Haskell werden abstrakte Datentypen mit Hilfe des Modul-Konzepts implementiert Prof. Dr. Margarita Esponda 15 Module in Haskell Ein Haskell-Modul ist eine Datei mit folgender Struktur: module <Name> (<Exportliste>) where • Nur die Datentypen und Funktionen, die in <Exportliste> angegeben werden, sind nach außen sichtbar. • Wenn <Exportliste> weggelassen wird, sind alle Definitionen automatisch nach außen sichtbar. Prof. Dr. Margarita Esponda 16 Module in Haskell module Stapel (Stapel, push, pop, top, emptyStack, isEmpty, show) where emptyStack :: Stapel a isEmpty :: Stapel a -> Bool push :: a-> Stapel a -> Stapel a pop :: Stapel a -> Stapel a top :: Stapel a -> a data Stapel a = Empty | S a (Stapel a) ... Prof. Dr. Margarita Esponda 17 Module in Haskell module Stapel ... emptyStack = Empty isEmpty Empty = True isEmpty _ = False push x s = S x s pop Empty = error "pop from an empty stack ..." pop (S _ s) = s top Empty = error "top from an empty stack ..." top (S x _) = x Prof. Dr. Margarita Esponda 18