ALP I Funktionale Programmierung

Werbung
Funktionale Programmierung
ALP I
Funktionale Programmierung
Typ-Klassen
und
Algebraische Datentypen
SS 2013
Prof. Dr. Margarita Esponda
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Funktionen höherer Ordnung
Anwendungsbeispiel der zipWith-Funktion:
Skalar-Produkt von zwei Vektoren
v1 . v2
v1 = (x1, x2, .. , xn)
v2 = (y1, y2, .. , yn)
v1 . v2 = x1. y1 + x2 . y2 + .. + xn. yn
skalarProd ::[Int] -> [Int] -> Int
skalarProd xs ys
Prof. Dr. Margarita Esponda
= foldl (+) 0 (zipWith (*) xs ys)
Funktionale Programmierung
Funktionen höherer Ordnung
Folgende Funktion berechnet die Fibonacci-Zahlen in
linearer Zeit
O(n)
fibs :: [Integer]
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
fibs
tail fibs
zipWith (+)
0:1:1:2:3:5:8:...
1:1:2:3:5:...
1:2:3:5:8:...
Anwendungsbeispiel:
take 40 fibs
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Funktionen höherer Ordnung
Funktionskomposition
f
A
B
g
g
C
°f
(.) :: (b → c) → (a → b) → (a → c)
(.)
Beispiel:
g
f
x = (g (f x))
ungerade :: Integer -> Bool
ungerade = not . gerade
Prof. Dr. Margarita Esponda
Die O-Notation
Funktionen höherer Ordnung
Standardfunktion:
iterate :: (a -> a) -> a -> [a]
iterate f x = x : iterate f ( f x)
Die iterate-Funktion produziert eine unendliche Liste
[x, f(x), f(f(x)), f(f(f(x))), … ]
Anwendungsbeispiel:
iterate (+1) 1 ⇒ [1, 2, 3, 4, 5, 6, 7, 8, 9, 10,.....
ALP I: Margarita Esponda, 8. Vorlesung, 19.11.2012
5
Beispiel
Welches ist die längste Zeichenfolge, die sich
wiederholt?
aabcfdesababcdferfcsdeaedabcfdesabeda
aabcfdesababcdferfcsdeaedabcfdesabeda
LRS-Algorithmus
ALP I: Margarita Esponda, 8. Vorlesung, 19.11.2012
6
Beispiel
Anwendungen
- Linguistik
- Bioinformatik
(DNA-Analyse)
- Datenkompression
- Untersuchung
von Plagiaten
- Antiviren-Software
- Musik-Analyse
- usw.
ALP I: Margarita Esponda, 8. Vorlesung, 19.11.2012
7
Die O-Notation
Lösung mit Brute-Force
aabcfdesababcdferfcsdeaedabcfdesabeda
i
j
Für alle Startpositionen (i, j) müssen wir das längste Präfix finden.
Anzahl der i, j Kombinationen = (n-1) + (n-2) + … + 2 + 1 = O(n2)
ALP I: Margarita Esponda, 8. Vorlesung, 19.11.2012
8
Die O-Notation
Lösung mit Sortieralgorithmen
aacfdebdabcfdebeda
acfdebdabcfdebeda
cfdebdabcfdebeda
fdebdabcfdebeda
debdabcfdebeda
ebdabcfdebeda
bdabcfdebeda
dabcfdebeda
abcfdebeda
bcfdebeda
cfdebeda
fdebeda
debeda
ebeda
beda
eda
da
a
ALP I: Margarita Esponda, 8. Vorlesung, 19.11.2012
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[ "a a c f d e b d a b c f d e b e d a",
"a c f d e b d a b c f d e b e d a",
"c f d e b d a b c f d e b e d a",
"f d e b d a b c f d e b e d a",
"d e b d a b c f d e b e d a",
"e b d a b c f d e b e d a",
"b d a b c f d e b e d a",
"d a b c f d e b e d a",
"a b c f d e b e d a",
"b c f d e b e d a",
"c f d e b e d a",
"f d e b e d a",
"d e b e d a",
"e b e d a",
"b e d a",
Suffixe oder Startpositionen
"e d a",
innerhalb der gesamten
"d a",
Zeichenketten
"a"]
9
Die O-Notation
Lösung mit Sortieralgorithmen
a
aacfdebd
abcfdebe
acfdebda
bcfdebed
bdabcfde
beda
cfdebeda
cfdebdab
da
dabcfdeb
debdabcf
debeda
ebdabcfd
ebeda
eda
fdebeda
fdebdabc
a
d
b
a
b
bcfdebeda
a
cfdebeda
eda
cfdebeda
eda
debeda
ebeda
fdebeda
ALP I: Margarita Esponda, 8. Vorlesung, 19.11.2012
Die Suffixe werden sortiert
17
0
8
1
9
6
14
10
2
16
7
4
12
5
13
15
11
3
10
Die O-Notation
Lösung mit Sortieralgorithmen
17
0
8
1
9
6
14
10
2
16
7
4
12
5
13
15
11
3
a
aacfdebd
abcfdebe
acfdebda
bcfdebed
bdabcfde
beda
cfdebeda
cfdebdab
da
dabcfdeb
debdabcf
debeda
ebdabcfd
ebeda
eda
fdebeda
fdebdabc
a
d
b
a
b
bcfdebeda
a
cfdebeda
eda
Die Präfix-Länge jeder zwei
benachbarten Suffixe werden
verglichen und das längste
cfdebeda
Präfix gesucht.
eda
debeda
ebeda
LRS-Algorithmus
fdebeda
ALP I: Margarita Esponda, 8. Vorlesung, 19.11.2012
11
Funktionale Programmierung
Überladung von Datentypen
Funktionen sollen oft auf verschiedene Datentypen anwendbar
sein, aber nicht auf beliebige Datentypen.
Beispiel:
Die (+) Funktion oder die anderen arithmetischen Operationen
sollen auf die Datentypen Int und Double anwendbar sein, aber
nicht auf andere Datentypen.
1+2
2.5 + 3.4
Das wird gelöst, indem Typ-Klassen definiert werden.
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Typ-Klassen
Mit Typ-Klassen lassen sich in Haskell Typen zusammenfassen,
die ähnliche Operationen unterstützen.
Variabler Datentyp
Beispiel:
(+) :: Num a => a -> a -> a
Klassenname
Die Typ-Variable a kann alle Instanzen der Num-Typklasse
annehmen.
Die Funktion wird dann für alle Datentypen, die eine Instanz der NumKlasse sind, definiert.
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Definition von Typ-Klassen
Vordefinierte Typklassen:
Beispiel:
class
Eq a where
(==) :: a - > a -> Bool
instance Eq Int where
(==) = intEq
-- intEq ist die primitive Funktion, die zwei
ganze Zahlen auf Gleichheit testet.
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Definition von eigenen Typ-Klassen
Eine Typ-Klasse deklariert eine Familie von Funktionen,
die für verschiedene Typen unterschiedlich definiert sein
können.
Allgemeine Syntax:
class C a where
f1 :: t1
f2 :: t2
…
fn :: tn
Prof. Dr. Margarita Esponda
Typ-Variable
Die Typen ti müssen die
Typ-Variable a enthalten
Funktionale Programmierung
Typ-Klassen in Haskell
Eine Typ-Klasse ist eine Sammlung von Typen, auf
denen eine in der Typ-Klasse festgelegte Menge
von Funktionen definiert ist.
Die Typ-Klasse Num stellt z. B. die Sammlung der
numerischen Datentypen Int, Integer, Float,
Double usw. dar, auf denen die Funktionen
(+), (*), usw. definiert sind.
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Typ-Klassen in Haskell
Die vordefinierte Num-Typ-Klasse sieht vereinfacht
so aus:
class Num a where
(+) :: a -> a
-> a
(-)
:: a -> a
-> a
(*)
:: a -> a -> a
negate :: a -> a
abs :: a -> a
signum :: a -> a
...
Typ-Klassen schreiben eine Schnittstelle vor.
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Typ-Klassen in Haskell
Alle Typen, die Instanzen von Ord sein sollen,
müssen die vorgeschriebenen Vergleichsoperationen
implementieren.
class Ord a where
(<)
:: a -> a
-> Bool
(<=)
:: a -> a
->
(>)
:: a -> a ->
Bool
(>=)
:: a -> a ->
Bool
max
:: a -> a -> a
min
:: a -> a -> a
…
Prof. Dr. Margarita Esponda
Bool
Funktionale Programmierung
Eigene Datentypen definieren
Typ-Synonyme
Ein vorhandener Datentyp wird umbenannt
Algebraische Datentypen
Neue Datentypen werden definiert mit Hilfe von
sogenannten Typ-Konstruktoren.
data
Prof. Dr. Margarita Esponda
Typ-Name = K1 | K2 | … | Kn
Funktionale Programmierung
Algebraische Datentypen
Allgemeine Form:
data
T a1 …ak =
K1 t11 … t1m
1
| K2 t21 … t2m
2
|…
| Kn tn1 … tnm
n
Die Ki sind Konstruktoren und die ai sind die TypParameter des neuen Datentyps T.
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Algebraische Datentypen
Beispiele:
einfache Aufzählungen
data Bool = True | False
data Move = Left | Right | Up | Down
type Position = (Int, Int)
Funktionsbeispiel:
move
move
move
move
move
Prof. Dr. Margarita Esponda
:: Move -> Position -> Position
Left (x,y) = (x-1,y)
Right (x,y) = (x+1,y)
Up
(x,y) = (x,y+1)
Down (x,y) = (x,y-1)
Funktionale Programmierung
Algebraische Datentypen
Beispiel:
data Weekday = Mo | Tu | We | Th | Fr | Sa | Su
isWeekend :: Weekday -> Bool
isWeekend Sa = True
isWeekend Su = True
isWeekend _ = False
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Algebraische Datentypen
Beispiel:
data Weekday = Mo | Tu | We | Th | Fr | Sa | Su
Mo == Mo
=> No instance for (Eq Weekday)
arising from a use of `==' at <interactive>:1:0-5
Possible fix: add an instance declaration for
(Eq Weekday)
Wir brauchen eine eigene
Gleichheits-Operation
1. Lösung
equal :: Weekday -> Weekday -> Bool
equal Mo Mo = True
equal Tu Tu = True
...
equal _ _ = False
instance Eq Weekday where
x == y = equal x y
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Algebraische Datentypen
2. Lösung
data Weekday = Mo | Tu | We | Th | Fr | Sa | Su
deriving (Eq, Ord, Show)
Instanzen dieser Klassen werden automatisch
aus der Typdefinition abgeleitet.
Eq
Gleichheit und Ungleichheit lässt sich durch Mustervergleich ableiten
Ord
verwendet die Reihenfolge der Konstruktoren in der Typdefinition
Mo < Tu < .. < Su
Show
Die Namen der Konstruktoren werden in Zeichenketten verwandelt
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Algebraische Datentypen
data Weekday = Mo | Tu | We | Th | Fr | Sa | Su
deriving (Eq, Ord, Show, Enum)
Damit haben wir automatisch alle Vergleichsoperationen, eine
show-Funktion für die Ausgabe von Ausdrücken und AufzählungsFunktionen wie succ, pred, fromEnum usw.
Wir können sogar Listengeneratoren oder Sequenzlisten
verwenden!
isWorkday :: Weekday -> Bool
isWorkday day = elem day [Mo .. Fr]
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Algebraische Datentypen
Typ-Konstruktoren mit Typen als Argumente
Beispiel:
data Temperatur = Celsius Double | Fahrenheit Double
| Kelvin Double
deriving Show
Die Show-Funktion wird abgeleitet
celsius2Kelvin :: Temperatur -> Temperatur
celsius2Kelvin (Celsius cel) = Kelvin (cel + 273.16)
fahrenheit2Celsius :: Temperatur -> Temperatur
fahrenheit2Celsius (Fahrenheit fah) = Celsius ((fah-32)*5/9)
Prof. Dr. Margarita Esponda
Die O-Notation
Algebraische Datentypen
data Bit = On | Off
deriving (Show)
instance Eq Bit
where
(==) On On = True
(==) Off Off = True
(==) On Off = False
(==) Off On = False
ALP I: Margarita Esponda, 8. Vorlesung, 19.11.2012
27
Funktionale Programmierung
Algebraische Datentypen
type Point = (Double, Double)
type Side = Double
type Center = Point
type Radius = Double
type Vertex = (Double, Double)
data Shape = Circ Center Radius | Rect Point Point | CPoly [Vertex]
deriving (Eq, Show)
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Algebraische Datentypen
area :: Shape-> Double
area (Circ _ r) = pi*r*r
area (Rect (x1, y1) (x2, y2)) = abs ((x2-x1) * (y2-y1))
area (CPoly ps) | length ps < 3 = 0
area (CPoly (p1:p2:p3:ps)) = triangleArea p1 p2 p3 +
area (CPoly (p1:p3:ps))
triangleArea :: Vertex -> Vertex -> Vertex -> Double
triangleArea (x1,y1) (x2,y2) (x3,y3) =
abs ((x2-x1)*(y3-y1) - (x3-x1)*(y2-y1)) / 2
Prof. Dr. Margarita Esponda
Die O-Notation
Algebraische Datentypen
myDiv :: Float -> Float -> Float
myDiv x 0 = error "Division by zero"
Wir möchten aber keine
Fehlermeldung
myDiv x y = x / y
data Maybe a = Nothing | Just a
safeDiv :: Float -> Float -> Maybe Float
safeDiv x 0 = Nothing
safeDiv x y = Just (x / y)
ALP I: Margarita Esponda, 8. Vorlesung, 19.11.2012
safeIDiv :: Int -> Int -> Maybe Int
safeIDiv n m = if m == 0
then Nothing
else Just (n `div` m)
30
Herunterladen