Zusammenfassung

Werbung
Deklarative (= fortgeschrittene) Programmierung
Teile der Lehrveranstaltung:
I
I
Vorlesung
Hausaufgaben:
I
I
I
Übungssserien
autotool
Praktika
Inhalt
I
Terme, Haskell-Ausdrücke
I
Termersetzungssysteme
I
algebraische Datentypen
Pattern Matching
I
Typen, Polymorphie
I
Typinferenz, Unifikation
I
Typklassen zur Steuerung der Polymorphie
I
Rekursive Datenypen
I
Lambda-Kalkül
I
Funktionen höherer Ordnung
I
Rekursionsschemata fold, map, filter, ...
I
Bedarfsauswertung
I
unendliche Datenstrukturen
Terme, Haskell-Ausdrücke
I
mehrsortige (funktionale) Signatur Σ
Haskell-Beispiel ( ÜA 1.3 ) :
square :: Int -> Int
mini :: Int -> Int -> Int
sum3 :: Int -> Int -> Int -> Int
eq2of3 :: Int -> Int -> Int -> Bool
I
Terme über Σ
Haskell-Beispiel:
t = eq2of3 (sum3 3 2 (square 2))
(mini (sum3 3 2 2) (square 2))
(square 3)
I
Positionen in Termen
z.B. [0, 2, 0] ∈ Pos(t), [0, 2, 1] 6∈ Pos(t)
I
Teilterme an Positionen
t[0,2,0] = 2, t[0,2] = square 2
ÜA: alle Positionen in t
Unifikation
I
Substitutionen t[p := s]
I
unifizierbare Terme
I
allgemeinster Unifikator zweier Terme
ÜA 4.1: allgemeinste Unifikatoren von
R(a, x) , R(y , y )
f (g(x), z) , f (g(y ), g(z))
f (g(x), y ) , f (y , h(x))
f (x, g(x)) , f (g(y ), y )
f (x, g(y )) , f (g(y ), x)
f (y , g(a, z)) , f (b, g(a, b))
f (y , g(x, y )) , f (b, g(a, y ))
f (y , g(x, x)) , f (b, g(a, y ))
f (y , g(x, y )) , f (h(z), g(a, z))
Termersetzung
I
Termersetzungsregel = Paar von Termen,
z.B. (m(B(x, y , z), m(x)), Noation m(B(x, y , z) → m(x)
I
Termersetzungssystem:
Menge von Termersetzungsregeln,
z.B. {m(B(L, y , z) → y , m(B(x, y , z) → m(x)}
I
Ableitung im Termersetzungssystem,
z.B. m(B(B(L, 3, x), 5, x) → m(B(L, 3, x)) → 3
I
Redex, Normalform
Auswertung von Termen (Bestimmung des Wertes):
Ableitung bis zu einer Normalform
Haskell-Funktionsdeklarationen sind Termersetzungsregeln.
Haskell-Programme sind Termersetzungssysteme
(Konstruktorsysteme).
Beispiele:
head (x : xs) = x
second xs = head ( tail xs )
einsen = 1 : einsen
Algebraische Datentypen
Datentypen:
einfach Int, Bool, Char, ...
zusammengesetzt durch Mengenoperationen ∪, ×, →
Haskell-Beispiele:
data Unit = ()
data Bool = True | False
data Pos = A | B | C
data Punkt = Punkt {x :: Float, y :: Float}
data Shape = Circle {mp :: Punkt,
rad :: Float}
| Rect {ol, ur :: Punkt}
data Maybe a = Nothing | Just a
ÜA 3.3: alle Werte vom Typ Maybe (Bool, Maybe ())
Polymorphie
Typvariablen a,b,c,...
Typinferenzregel:
f :: A → B e :: A
f e :: B
ÜA 4.2: allgemeinster Typ des Haskell-Ausdrucks
fst ( head ( f x ) )
für
f :: ( [ a ] , b ) -> [ ( b , a ) ]
x = ("foo", [ ( 2 , Just _ , True ) ] )
Pattern Matching
data T = C1 ...
| C2 ...
typisches Vorgehen beim Programmieren einer Funktion
f :: T -> ...
für jeden Konstruktor des Datentyps ein Zweig in der
Fallunterscheidung
f x = case x of
C1 ... -> ...
C2 ... -> ...
Typklassen
data Ordering = LT | EQ | GT
class Ord a where
compare :: a -> a -> Ordering
instance Ord Nat
compare Z Z =
compare Z _ =
compare _ Z =
compare (S x)
where
EQ
LT
GT
(S y) = compare x y
data Bool = True | False
instance Show Bool where
show True = "wahr"
show False = "falsch"
oder automatisch
data Bool = True | False
deriving Show
ÜA 7.3: Eq-Instanz für Peano-Zahlen
Eingeschränkte Polymorphie
Typ-Contraints f :: TC a => ...
für jeden Typ a, für den eine TC-Instanz definiert wurde
(und damit die Methoden dieser Typklasse definiert)
Haskell-Beispiele (ÜA 1.3):
square :: Num a => a -> a
square x = x * x
mini :: Ord a => a -> a -> a
mini x y = if x < y then x else y
sum3 :: Num a => a -> a -> a -> a
sum3 x y z = x + y + z
eq2of3 :: Eq a => a -> a -> a -> a -> Bool
eq2of3 x y z = not ((x == y) && (x == z))
&& ((x == x) || (x == z) || (y == z))
Rekursive Datentypen
I
Peano-Zahlen
I
Listen
I
Binärbäume mit Schlüsseln in inneren Knoten
I
ÜA 6.3: Binärbäume mit Schlüsseln in Blättern
I
Formeln (ÜA 7.4):
Datentyp Formel zur Repräsentation variablenfreier
aussagenlogischer Formeln mit den Junktoren (¬, ∨, ∧, →)
mit Wahrheitswertkonstanten in den Blättern
Strukturelle Induktion
für rekursive Datentypen
data T = C1 | .. | Cn |
Nachweis, dass jedes Element des Typs T die Eigenschaft p erfüllt
durch
strukturelle Induktion
IA: p gilt für alle nullstelligen Konstruktoren C1, ..., Cn
IS: für jeden k -stelligen Konstruktor D:
IV: p gilt für t1, ..., tk
IB: p gilt für D t1 ... tk
ÜA 2.3.b: Addition auf Peano-Zahlen ist kommutativ
sum = fold 0 (+)
sum ( append xs ys ) = sum xs + sum ys
ÜA 2.4.d: reverse [x] = [x], reverse (reverse xs) = xs
Funktionen höherer Ordnung
Beispiel:
head :: [ a ] -> a
head ( x : _ ) = x
als anonyme Funktion (Lambda-Ausdruck)
\ ( x
: _ ) -> x
als Argument einer Funktion höherer Ordnung
map :: ( a -> b ) -> [ a ] -> [ b ]
map (\ ( x
: _ ) -> x ) ["foo" ,"bar"] = "fb"
Lambda-Kalkül
Syntax:
I
Abstraktion, Applikation
I
freie, gebundene Variablen
I
Redexe
I
gebundene Umbenennung
Semantik: β-Reduktion
ÜA 8.2.d: (λxyz.xz(yz))(λxy .x)(λxy .x)c reduzieren
Auswertung von ( \ y -> ( \ x -> x * y ) ) 3 4
Rekursionsmuster
I
fold für
I
I
I
I
map für
I
I
I
Peano-Zahlen
Listen
Bäume
Listen
Bäume
filter, zip, zipWith für Listen
ÜA 10.5: fold für aussagenlogische Formeln
Bedarfsauswertung
Bedarfsauswertung (lazy evaluation):
I
Reduktionsstrategie: leftmost outermost
I
mit Sharing
Beispiel: fst ( 1 + 2 ) ( 2 + 3 )
ermöglicht einfachen Umgang mit unendlichen Datenstrukturen
(z.B. Streams)
einsen :: [ Int ]
einsen = 1 : einsen
take 2 einsen
ÜA 10.1: sum $ map (\ n -> n * n) $ take 3 nats
Softwaretechnische Vorteile
der deklarativen Programmierung:
Beweisbarkeit : Rechnen mit Programmen wie in der
Mathematik mit Termen
Sicherheit : es gibt keine Nebenwirkungen
und Wirkungen sieht man bereits am Typ
Wiederverwendbarkeit : durch Funktionen höherer Ordnung
(Entwurfsmuster)
Effizienz : durch Programmtransformationen im Compiler
Parallelisierbarkeit : durch Nebenwirkungsfreiheit
Herunterladen