Ausdrücke auswerten

Werbung
Ausdrücke auswerten
Im Haskell-Interpreter können Ausdrücke direkt ausgewertet werden:
Prelude> 42
42
Prelude> 5*3
15
Interpreter gibt Repräsentation des Wertes aus
1
Ausdrücke über Ganzzahlen
• Konstanten: 1, 3, 42, 321432343243245
• Arithmetische Ausdrücke: 1+2, 4*2, 5+2*7, - 4
• Funktionsaufrufe: cos 2
2
Definitionen
Eine Definition ist eine Gleichung:
• name = expr
z.B. pi = 3.14
Macht name im ganzen Programm verfügbar
Progamm = Reihe von Definitionen
3
Definitionen laden
Nach dem Start des Interpreters sind die Definitionen aus der
Prelude verfügbar
Weitere Definitionen müssen geladen werden:
:load filename
Haskell-Dateien sollten die Endung .hs haben
Inhalt der Dateien: Reihe von Gleichungen
4
Bezeichner in Haskell
• Erstes Zeichen: Kleinbuchstabe
• Dann Buchstaben, Zahlen und '
• Bsp: abs, abs', splitAt, writeFile, zip3
5
Funktionsdefinition
Mathematik: f(x) = cos(x) + 2
Haskell: name var ... = expr
z.B.
f x = cos x + 2
square x = x * x
minus x y = x - y
6
Funktionsdefinition durch Fallaufzählung
1+1=2
1+2=3
2+3=5
In Haskell:
add 1 1 = 2
add 1 2 = 3
add 2 5 = 7
Auch dabei Variablen möglich:
add' 0 x = x
add' 1 1 = 2
add' 1 2 = 3
Bei Überlappung: Erster von oben
7
Auswertung von Definitionen: Vereinfachen
Wenn die rechte Seite einer Definition auf einen Ausdruck passt,
ersetze den Ausdruck durch die linke Seite der Definition.
1 + 1
= 2
add 2 5
= 7
1 + (2 * pi) = 1 + 6.28
8
Auswertung von Funktionsaufrufen: Einsetzen
Enthält die rechte Seite Variablen, so ersetze die Variablen durch die
entsprechenden Argumente
f (4 * 3)
= cos (4 * 3) + 2
1 + (square (1 + 2))
= 1 + ((1 + 2) * (1 + 2))
minus (1 * 1) (4 / 2) = (1 * 1) - (4 / 2)
9
Normalform
Kann ein Ausdruck nicht mehr weiter ausgewertet werden, so ist er in
Normalform.
Bsp: 12, 3.14, minus
10
Auswertungsreihenfolge
Wichtige Eigenschaft der Funktionalen Programmierung:
Wenn zwei Auswertungsfolgen terminieren, so liefern sie dieselbe
Normalform.
11
Bsp: Alternative Auswertungsreihenfolgen
square (3 + 4) = square 7 = 7*7 = 49
square (3 + 4) = (3 + 4) * (3 + 4) = 7 * (3 + 4) =
7 * 7 = 49
square (3 + 4) = (3 + 4) * (3 + 4) = (3 + 4) * 7 =
7 * 7 = 49
12
Auswertungsstrategie
Eine Auswertungsstrategie legt eine bestimmte
Auswertungsreihenfolge fest.
Beispiele: Call-by-Name, Call-by-Value
Später: Lazy-Evaluation als Strategie für Haskell
13
Werte
Ein Ausdruck beschreibt einen Wert
Mögliche Arten von Werte: Zahlen, Boolean, Zeichen, Tupel, Listen,
Funktionen, ...
14
Kanonische Repräsentation
Werte sind abstrakt, Ausdrücke repräsentieren Werte
Haskell-Interpreter gibt für einen Wert seine
kanonische Repräsentation aus
Manche Werte haben keine kanonische Rep., z.B. Funktionen oder
π
15
Bottom
Manche Ausdrücke repräsentieren keine wohldefinierten Werte
Programm: infinity = infinity + 1
infinity
1 / 0
Spezieller Wert: ⊥
16
Striktheit
Wenn f ⊥ = ⊥, dann ist f eine strikte Funktion, sonst ist f eine
nicht-strikte Funktion
Lazy-Evaluation erlaubt es, nicht-strikte Funktion zu definieren:
three x = 3
three infinity = 3
17
Rekursive Definitionen
fact n = if n == 0 then 1 else n * fact (n - 1))
Auswertung mit Vereinfachen und Einsetzen:
fact 1 = if 1 == 0 then 1 else 1 * fact (1 - 1) =
1 * fact (1 - 1) =
1 * (if (1 - 1) == 0 then 1 else (1 - 1) * fact ((1 = 1 * (if (0 == 0) then 1 else ... = 1 * 1 = 1
18
Typen
Typ = Menge von Werten
Typ für Zahlen: Integer
Typ für Funktionen: t1 ->... tN -> tR
Wobei t1... tN die Typen der Argumente und tR der Typ des
Ergebnisses sind.
Bsp: Typ von add: Integer -> Integer -> Integer
Kommando :type expr liefert Typ des Ausdrucks expr
19
Typsignaturen
Bei einer Definition kann der Typ mit angegeben werden =
Typsignatur.
Syntax: name :: typ
Bsp:
square :: Integer -> Integer
square x = x * x
20
Vorteile von Typsignaturen
• Teil des Designs: Man macht sich erste Gedanken über Ein- und
Ausgabe
• Bessere Fehlermeldungen, denn der Compiler liest die Signaturen
zuerst
• Teil der Dokumentation: Leser kennt sofort den Typ der
Ein/Ausgaben
⇒ Bei den Lösungen der Übungsaufgaben immer angeben
21
Funktionen sind einstellig
Funktionen in Haskell sind in Wahrheit einstellig:
f x y = e definiert eine einstellige Funktion, die eine einstellige
Funktion zurückgibt:
fTwo = f 2 hat Typ Integer ->> Integer
fTwo 3 ≡ (f 2) 3 ≡ f 2 3
Currying
22
Funktionstypen
-> ist rechtsassoziativ
Integer -> Integer -> Integer ist gleich
Integer -> (Integer -> Integer)
23
Currying erleichtert Wiederverwendung
twice :: (Integer -> Integer) -> Integer -> Integer
twice f x = f (f x)
quad :: Integer -> Integer
quad = twice square
24
Boolsche Werte
Eigener Typ: Bool
Werte des Typs:
• Wahr True
• Falsch False
25
Boolsche Werte
Operatoren: &&, ||, not, ==
exOr :: Bool -> Bool -> Bool
exOr x y = (x || y) && not (x && y)
Alternative Definition:
exOr True x = not x
exOr False x = x
26
Bedingte Ausdrücke
Ganz normales if
Syntax: if test-expr then cons-expr else alt-expr
• test-expr muss vom Typ Boolean sein
• cons-expr und alt-expr müssen vom gleichen Typ sein
27
Auswertung für bedingte Ausdrücke
Wenn test-expr True ist, ersetze den if-Ausdruck durch
cons-expr, wenn test-expr False ist, ersetze den if-Ausdruck
durch alt-expr.
Bsp: 1 + (if True 4 else 42) = 1 + 4 = 5
neg :: Bool -> Bool
neg test = if test False else True
28
Operatoren
Def: Ein Operator ist eine Funktion, die infix aufgerufen wird
In Haskell wird jede binäre Funktion durch Backquotes zum
Operator:
Bsp: 3 `smallerc` 4 entspricht smallerc 3 4
Auch in Definition möglich
Umgekehrt wird jeder Operator in Klammern zur binären Funktion:
Bsp: (+) 3 4 entspricht 3 + 4
29
Sektionen
Sektion: Binärer Operator auf nur ein Argument angewendet.
Ergebnis ist eine Funktion:
(*
(>
(1
(+
2)
0)
/)
1)
-----
Verdoppeln
Test auf positive Zahl
Kehrwert
Nachfolger
Aber: (- 2) ist unäre Negation
30
Funktionskomposition
In der Mathematik: f ⋅ g(x) = f(g(x))
In Haskell: Operator .
Es gilt also (f . g) x ist gleich f (g x)
31
Herunterladen