4 auf 1

Werbung
3. Funktionales Programmieren
3.1 Grundkonzepte funktionaler Programmierung
3. Funktionales Programmieren
Beschreibung von Werten:
Beschreibung von Werten: (2)
• durch geschachtelte Anwendung von Funktionen:
• mittels Konstanten oder Bezeichnern für Werte:
45.67 + 6857 * (-9)
floor ( -3.4) * truncate ( -3.4)
toEnum ((( fromEnum (last("Urin"++" stinkt ")))+2))::Char
23
"Ich bin eine Zeichenreihe "
True
x
• durch Verwendung des bedingten Ausdrucks (engl. conditional
• durch direkte Anwendung von Funktionen:
expression):
abs ( -28382)
"Urin" ++ " stinkt "
not True
©Arnd Poetzsch-Heffter
3.1 Grundkonzepte funktionaler Programmierung
if <boolAusdruck > then <Ausdruck >
else <Ausdruck >
TU Kaiserslautern
3. Funktionales Programmieren
193
©Arnd Poetzsch-Heffter
3.1 Grundkonzepte funktionaler Programmierung
TU Kaiserslautern
3. Funktionales Programmieren
3.1 Grundkonzepte funktionaler Programmierung
Begriffsklärung: (Ausdruck, expression)
Begriffsklärung: (Ausdruck, expression) (2)
Ausdrücke sind das Sprachmittel zur Beschreibung von Werten. Ein
Ausdruck (engl. expression) in Haskell ist
Jeder Ausdruck hat einen Typ:
• Der Typ einer Konstanten ergibt sich aus der Signatur.
• eine Konstante,
• Der Typ eines Bezeichners ergibt sich aus dem Wert, den er
bezeichnet.
• ein Bezeichner (Variable, Name),
• Der Typ einer Funktionsanwendung ist der Ergebnistyp der
• die Anwendung einer Funktion auf einen Ausdruck,
Funktion.
• ein bedingter Ausdruck gebildet
• Der Typ eines if-then-else-Ausdrucks ist gleich dem Typ des
• oder ist mit Sprachmitteln aufgebaut, die erst später behandelt
Ausdruck im then- bzw. else-Zweig.
werden.
©Arnd Poetzsch-Heffter
194
TU Kaiserslautern
195
©Arnd Poetzsch-Heffter
TU Kaiserslautern
196
3. Funktionales Programmieren
3.1 Grundkonzepte funktionaler Programmierung
3. Funktionales Programmieren
Präzedenzregeln:
3.1 Grundkonzepte funktionaler Programmierung
Präzedenzregeln: (2)
Präzedenzregeln legen fest, wie Ausdrücke zu strukturieren sind:
• Am stärksten binden Funktionsanwendungen in Präfixform.
• Regeln für Infix-Operatoren:
Wenn Ausdrücke nicht vollständig geklammert sind, ist im Allg. nicht
klar, wie ihr Syntaxbaum aussieht.
infixl 7 ∗, /, div, mod
infixl 6 +, −
infix 4 ==, / =, <, >, <=, >=
infixr 3 &&
infixr 2 ||
Je höher die Präzedenzzahl, desto stärker binden die
Operationen.
Beispiele:
3 == 5 == True
False == True || True
False && True || True
• Mit “infixl”/“infixr” gelistete Operatoren sind links-/rechtsassoziativ,
d.h. sie werden von links/rechts her geklammert.
• Mit “infix” gelistete Operatoren müssen geklammert werden.
©Arnd Poetzsch-Heffter
TU Kaiserslautern
3. Funktionales Programmieren
197
3.1 Grundkonzepte funktionaler Programmierung
198
3.1 Grundkonzepte funktionaler Programmierung
Begriffsklärung: (Vereinbarung, Deklaration, Bindung)
In Programmiersprachen dienen Vereinbarungen oder Deklarationen
(engl. declaration) dazu, den in einem Programm verwendeten
Elementen Bezeichner/Namen zu geben.
Bisher haben wir Ausdrücke formuliert, die sich auf die vordefinierten
Funktions- und Konstantenbezeichner von Haskell gestützt haben.
Syntaktisch gesehen heißt Programmierung:
Dadurch entsteht eine Bindung (n, e) zwischen dem Bezeichner n
und dem bezeichneten Programmelement e.
• neue Typen, Werte und Funktionen zu definieren,
• die neu definierten Elemente unter Bezeichnern zugänglich zu
An allen Programmstellen, an denen die Bindung sichtbar ist, kann der
Bezeichner benutzt werden, um sich auf das Programmelement zu
beziehen.
machen.
TU Kaiserslautern
TU Kaiserslautern
3. Funktionales Programmieren
Deklaration und Bezeichnerbindung:
©Arnd Poetzsch-Heffter
©Arnd Poetzsch-Heffter
199
©Arnd Poetzsch-Heffter
TU Kaiserslautern
200
3. Funktionales Programmieren
3.1 Grundkonzepte funktionaler Programmierung
3. Funktionales Programmieren
Bemerkung:
Wertvereinbarungen:
• Die verschiedenen Arten an Programmelementen, die in
• Wertvereinbarungen haben (u.a.) die Form:
Deklarationen vorkommen können, hängen von der
Programmiersprache ab.
<Bezeichner >
• In Haskell sind es im Wesentlichen:
1. Bezeichnervereinbarungen (nur zusammen mit
Wert-/Funktionsvereinbarung)
2. Wertvereinbarungen
3. Vereinbarungen (rekursiver) Funktionen
4. Vereinbarungen benutzerdeklarierter Typen
3. Funktionales Programmieren
<Ausdruck > ;
voranstellen, um den Typ des Bezeichners zu deklarieren:
<Bezeichner > :: <Typ > ;
<Bezeichner > = <Ausdruck > ;
Der Typ des Ausdrucks muss gleich dem vereinbarten Typ sein.
• Der rechtsseitige Ausdruck darf nur sichtbare Bezeichner
festlegen, sind ebenfalls sprachabhängig und können sehr
komplex sein. Wir führen die Sichtbarkeitsregeln schrittweise ein
TU Kaiserslautern
=
• Wertvereinbarungen kann man eine Bezeichnervereinbarung
• Die Regeln, die die Sichtbarkeit von Bindungen bzw. Bezeichern
©Arnd Poetzsch-Heffter
3.1 Grundkonzepte funktionaler Programmierung
enthalten.
201
©Arnd Poetzsch-Heffter
TU Kaiserslautern
3.1 Grundkonzepte funktionaler Programmierung
3. Funktionales Programmieren
Beispiele: (Wertvereinbarungen)
202
3.1 Grundkonzepte funktionaler Programmierung
Beispiele: (Wertvereinbarungen) (2)
Einzeilige Vereinbarungen im Interpreter ghci:
let b = 56 ;
b = 56 ;
Mehrzeilige Vereinbarungen im Interpreter ghci:
a::Int
a = 7
:{
let {
a::Int
a = 7
sieben
sieben
flag
dkv
}
:}
sieben
sieben
flag
dkv
:: Float ;
= 7.0 ;
= floor sieben == truncate (- sieben )
= " Deutscher Komiker Verein e.v."
©Arnd Poetzsch-Heffter
TU Kaiserslautern
203
©Arnd Poetzsch-Heffter
;
;
:: Float ;
= 7.0 ;
= floor sieben == truncate (- sieben ) ;
= " Deutscher Komiker Verein e.v."
TU Kaiserslautern
204
3. Funktionales Programmieren
3.1 Grundkonzepte funktionaler Programmierung
3. Funktionales Programmieren
Funktionsvereinbarungen:
3.1 Grundkonzepte funktionaler Programmierung
Beispiele: (Funktionsvereinbarungen)
Zwei Probleme:
1. Bisher haben wir keine Ausdrücke, die eine Funktion als Ergebnis
liefern (Ausnahme: Funktionsbezeichner)
2. Funktionen können rekursiv sein, d.h. der Funktionsbezeichner
kommt im definierenden Ausdruck vor.
myDivision :: Integer -> Integer -> Interger
myDevision = div
fac :: Integer -> Integer
-- Argument n muss >= 0 sein
fac n = if n==0 then 1 else n * fac (n -1)
Lösungen:
Zu 1. Erweitere die Menge der Ausdrücke, so dass Ausdrücke
Funktionen beschreiben können. Dann kann die obige
Wertvereinbarung genutzt werden.
plus2 :: Integer -> Integer
plus2 = (+) 2
Zu 2. Erlaube selbstbezügliche Deklarationen (Haskells Lösung) oder
benutze spezielle Syntax für rekursive Funktionsdeklarationen.
Genaueres dazu in Unterabschnitt 3.1.2 (Folien 215ff).
©Arnd Poetzsch-Heffter
TU Kaiserslautern
3. Funktionales Programmieren
205
©Arnd Poetzsch-Heffter
3.1 Grundkonzepte funktionaler Programmierung
TU Kaiserslautern
3. Funktionales Programmieren
3.1 Grundkonzepte funktionaler Programmierung
Typvereinbarungen:
Beispiele: (Typvereinbarungen)
Zwei Probleme:
type IntPaar
= (Int ,Int) ;
type CharList
= [Char] ;
type Telefonbuch =
[(( String ,String ,String ,Int) ,[ String ])] ;
1. Bisher haben wir keine Ausdrücke, die Typen als Ergebnis liefern.
2. Typen können rekursiv sein, d.h. der vereinbarte Typbezeichner
kommt im definierenden Typausdruck vor.
type IntegerNachInteger
Lösungen:
Zu 1. Führe “Ausdrücke” für Typen ein (z.B. Int -> Int).
Genaueres dazu in Unterabschnitt 3.1.4. (Folien 269ff).
TU Kaiserslautern
Integer -> Integer ;
fakultaet :: IntegerNachInteger ;
-- Argument muss >= 0 sein
fakultaet = fac ;
Zu 2. Benutze spezielle Syntax für rekursive Typdeklarationen.
©Arnd Poetzsch-Heffter
=
206
207
©Arnd Poetzsch-Heffter
TU Kaiserslautern
208
3. Funktionales Programmieren
3.1 Grundkonzepte funktionaler Programmierung
3. Funktionales Programmieren
Begriffsklärung: (Bezeichnerumgebung)
3.1 Grundkonzepte funktionaler Programmierung
Bemerkungen:
• Programmiersprachen stellen üblicherweise eine
Standard-Umgebung bereit mit den vordefinierten
Programmelementen (Werten, Funktionen, Typen, etc.). In Haskell
ist die Standard-Umgebung durch das Modul Prelude definiert.
Eine Bezeichnerumgebung ist eine Abbildung von Bezeichnern auf
Werte (einschl. Funktionen) und Typen, ggf. auch auf andersartige
Programmelemente.
• Eine Bezeichnerumgebung wird häufig als Liste von Bindungen
Oft spricht man auch von Namensumgebung oder einfach von
Umgebung (engl. environment).
modelliert (vgl. Folie 201).
• Jede Datenstruktur und jedes Modul definiert eine
Bezeichnerumgebung.
©Arnd Poetzsch-Heffter
TU Kaiserslautern
3. Funktionales Programmieren
209
©Arnd Poetzsch-Heffter
3.1 Grundkonzepte funktionaler Programmierung
TU Kaiserslautern
3. Funktionales Programmieren
Begriffsklärung: (Programm)
210
3.1 Grundkonzepte funktionaler Programmierung
Beispiel: (funktionales Programm)
import System .IO
fac :: Integer -> Integer
-- Argument n muss >= 0 sein
fac n = if n==0 then 1 else n * fac (n -1)
Ein Programm besteht in der Regel aus
• einer Menge von Deklarationen und
• einer (durch einen besonderen Namen) ausgezeichneten Funktion
bzw. Prozedur (oder ähnlichem Konstrukt), die angibt, wie die
Auswertung bzw. Ausführung des Programms zu starten ist.
©Arnd Poetzsch-Heffter
TU Kaiserslautern
211
main = do {
hSetBuffering stdout NoBuffering ;
putStr " Eingabe x (x>=0): ";
a <- readLn ;
putStr " Ergebnis (fac x): ";
print (fac a);
}
©Arnd Poetzsch-Heffter
TU Kaiserslautern
212
3. Funktionales Programmieren
3.1 Grundkonzepte funktionaler Programmierung
3. Funktionales Programmieren
Unterabschnitt 3.1.2
3.1 Grundkonzepte funktionaler Programmierung
Begriffsklärung: (Funktionsabstraktion
Eine Funktion kann man durch einen Ausdruck beschreiben, in dem
die Argumente der Funktion durch Bezeichner vertreten sind.
Um deutlich zu machen, welche Bezeichner für Argumente stehen,
werden diese deklariert. Alle anderen Bezeichner des Ausdrucks
müssen anderweitig gebunden werden.
Rekursive Funktionen
Diesen Schritt von einem Ausdruck zu der Beschreibung einer
Funktion nennt man Funktionsabstraktion oder λ-Abstraktion.
©Arnd Poetzsch-Heffter
TU Kaiserslautern
3. Funktionales Programmieren
213
©Arnd Poetzsch-Heffter
3.1 Grundkonzepte funktionaler Programmierung
TU Kaiserslautern
3. Funktionales Programmieren
Beispiele: Funktionsabstraktion
214
3.1 Grundkonzepte funktionaler Programmierung
Beispiele: Funktionsabstraktion (2)
2. Volumenberechnung eines Kegelstumpfes:
1. Quadratfunktion:
Ausdruck:
Abstraktion:
Haskell-Notation:
Formel:
Sei h die Höhe, rk , rg die Radien; dann ergibt sich das Volumen v zu
x ∗x
λx.(x ∗ x)
\ x -> (x * x)
π∗h
∗ (rk 2 + rk ∗ rg + rg 2 )
3
Haskell-Ausdruck für die rechte Seite:
v=
Vereinbarung eines Bezeichners für die Funktion:
(pi * h) / 3.0 * ( rk **2 + rk*rg + rg **2 )
quadrat = \ x -> (x * x)
Abstraktion in Haskell-Syntax und Vereinbarung von v:
v = \ h rk rg -> (pi*h)/3.0 * (rk **2+ rk*rg+rg **2)
©Arnd Poetzsch-Heffter
TU Kaiserslautern
215
©Arnd Poetzsch-Heffter
TU Kaiserslautern
216
Herunterladen