Funktionale Programmierung ALP I Abstrakte Datentypen SS 2011 Prof. Dr. Margarita Esponda Prof. Dr. Margarita Esponda Funktionale Programmierung Haskell Typsystem Monomorphe Funktionen Der Datentyp wird genau durch die Signatur bestimmt Beispiel: asciiCode :: Char -> Int Polymorphe Funktionen Typvariablen in der Signatur lassen beliebige Datentypen zu Beispiel: length :: [a] -> [a] Prof. Dr. Margarita Esponda Funktionale Programmierung Einschränkung von Typen Mit Hilfe von vordefinierten Typ-Klassen können polymorphe Funktionen mit Einschränkung definiert werden Verwendung eines Kontextes Beispiel: equalList :: Eq a => [a]->[a]->Bool nur für Datentypen mit Gleichheitsoperator add2List:: Num a => [a] -> a -> [a] add2List xs y = map (+y) xs nur numerische Typen mit definierten arithmetischen Operationen Prof. Dr. Margarita Esponda Funktionale Programmierung Einige vordefinierte Typ-Klassen Prof. Dr. Margarita Esponda Funktionale Programmierung Typ-Anpassung 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 stattfinden fromIntegral (mod 3 2) + 1.5 Prof. Dr. Margarita Esponda Funktionale Programmierung Typ-Klassen Typen werden durch die Operationen, die auf ihren Werten definiert werden sollen, beschrieben. Beispiel: Class (+) (*) (-) Prof. Dr. Margarita Esponda Num a where :: a -> a -> a :: a -> a -> a :: a -> a -> a Typklassen sind abstrakte Schnittstellen, weil keine Implementierung vorgegeben wird. Funktionale Programmierung Instanzen von Typ-Klassen Mit einer Instanz-Deklaration definieren wir, welche Typen zu welchen Typ-Klassen gehören. instance Num Int Vordefinierte primitive Funktionen where x+y = primAdd x y neg x = primNegateInt x ... instance Eq Char where x == y = ord c == ord d Prof. Dr. Margarita Esponda Funktionale Programmierung Instanzen von Typ-Klassen Der Instanz-Typ einer Klasse muss die vorgeschriebenen Operationen einer Typ-Klasse 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 Funktionale Programmierung Instanzen von Typ-Klassen 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 -> Bool 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 Funktionale Programmierung 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 Funktionale Programmierung Mehrere Oberklassen class Enum a where class Num a where fromEnum :: a -> Int (+) :: a -> a -> a toEnum neg :: a -> a :: Int -> a ... ... 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 Integral erbt die Operationen von Enum und Num, und fügt noch weitere Operationen hinzu. Ausprägungen von Integral müssen folglich auch Ausprägungen von Enum und Num sein. TypklassenHierarchie Funktionale Programmierung 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 Funktionale Programmierung Abstrakte Datentypen - sind Datentypen, die durch die auf ihren Werten erlaubten Operationen definiert sind, und dessen Implementierung den Nutzern des Typs verborgen (Datenkapselung) ist - in Haskell werden abstrakte Datentypen mit Hilfe des Modul-Konzepts implementiert Prof. Dr. Margarita Esponda Funktionale Programmierung 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 Funktionale Programmierung 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 Funktionale Programmierung 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