Praktische Informatik 3: Funktionale Programmierung Vorlesung 2 vom 21.10.2014: Funktionen und Datentypen
Christoph Lüth Universität Bremen Wintersemester 2014/15
Rev. 1843 1 [38]
Fahrplan
I Teil I: Funktionale Programmierung im Kleinen
IEinführung
IFunktionen und Datentypen
IRekursive Datentypen
ITypvariablen und Polymorphie
IFunktionen höherer Ordnung I
IFunktionen höherer Ordnung II
ITypinferenz
I Teil II: Funktionale Programmierung im Großen I Teil III: Funktionale Programmierung im richtigen Leben
2 [38]
Inhalt
I Organisatorisches I Definition vonFunktionen
I SyntaktischeFeinheiten
I Bedeutung von Haskell-Programmen
I Striktheit
I Definition vonDatentypen
I Aufzählungen
I Produkte
3 [38]
Organisatorisches
I Verteilung der Tutorien (laut stud.ip):
Mi 08 – 10 MZH 1110 Sören Schulze 11 Mi 10 – 12 MZH 1470 Sandor Herms 46 Mi 12 – 14 MZH 1110 Henrik Reichmann 19 Mi 14 – 16 SFG 1020 Felix Thielke 14
Do 08 – 10 MZH 1110 Jan Radtke 37
Do 10 – 12 MZH 1090 Daniel Müller 40
Nicht zugeordnet 30
I Insgesamt: 197 Studenten, optimale Größe: ca. 33 I Bitte auf die kleineren Tutorienumverteilen, wenn möglich.
4 [38]
Definition von Funktionen
5 [38]
Definition von Funktionen
I Zwei wesentlicheKonstrukte:
IFallunterscheidung
IRekursion Satz
Fallunterscheidung und Rekursion auf natürlichen Zahlen sind Turing-mächtig.
I Funktion kannpartiellsein.
6 [38]
Haskell-Syntax: Funktionsdefinition
Generelle Form:
I Signatur:
max :: Int→ Int→ Int I Definition:
max x y=i f x<y then y else x
I Kopf, mit Parametern
I Rumpf(evtl. länger, mehrere Zeilen)
I TypischesMuster: Fallunterscheidung, dann rekursiver Aufruf
I Was gehört zum Rumpf (Geltungsberereich)?
7 [38]
Haskell-Syntax: Charakteristika
I Leichtgewichtig
IWichtigstes Zeichen:
I Funktionsapplikation: f a
IKeineKlammern
IHöchstePriorität (engste Bindung)
I Abseitsregel: Gültigkeitsbereich durch Einrückung
IKeineKlammern
I Auch in anderenSprachen(Python, Ruby)
8 [38]
Haskell-Syntax I: Die Abseitsregel
Funktionsdefinition:
f x1x2. . .xn=E I Geltungsbereichder Definition von f:
alles, was gegenüber feingerücktist.
I Beispiel:
f x=h i e r faengts an und h i e r gehts weiter
immer weiter
g y z=und h i e r faengt was neues an I Gilt auchverschachtelt.
I Kommentare sindpassiv
9 [38]
Haskell-Syntax II: Kommentare
I Pro Zeile: Ab−−bis Ende der Zeile
f x y=irgendwas −−und hier der Kommentar!
I Über mehrere Zeilen: Anfang{−, Ende−}
{−
Hier faengt der Kommentar an e r s tr e c k t sich ueber mehrere Zeilen
b i s h i e r −}
f x y=irgendwas
IKann geschachtelt werden.
10 [38]
Haskell-Syntax III: Bedingte Definitionen
I Statt verschachtelter Fallunterscheidungen . . . f x y=i f B1thenP else
i f B2thenQelse. . . . . .bedingte Gleichungen:
f x y
| B1=. . .
| B2=. . .
I Auswertung der Bedingungen von oben nach unten I Wenn keine Bedingung wahr ist:Laufzeitfehler! Deshalb:
| otherwise=. . .
11 [38]
Haskell-Syntax IV: Lokale Definitionen
I Lokale Definitionen mitwhereoderlet:
f x y
| g=P y
| otherwise=Qwhere y=M
f x=N x
f x y= let y=M
f x=N x in i f g thenP y
elseQ I f, y, . . . werdengleichzeitigdefiniert (Rekursion!) I Namen f, y und Parameter (x)überlagernandere I Es gilt dieAbseitsregel
IDeshalb:Aufgleiche Einrückungder lokalen Definition achten!
12 [38]
Bedeutung von Funktionen
13 [38]
Bedeutung (Semantik) von Programmen
I OperationaleSemantik:
IDurch denAusführungsbegriff
IEin Programm ist, was es tut.
I DenotationelleSemantik:
IProgramme werden aufmathematische Objekteabgebildet (Denotat).
IFür funktionale Programme:rekursivdefinierte Funktionen Äquivalenz von operationaler und denotationaler Semantik
SeiPein funktionales Programm,→P die dadurch definierte Reduktion, und[[P]]das Denotat. Dann gilt für alle Ausdrücketund Wertev
t→Pv ⇐⇒ [[P]](t) =v
14 [38]
Auswertungsstrategien
inc :: Int → Int inc x=x+1
double :: Int → Int double x=2∗x I Reduktion von inc (double ( inc 3))
I Vonaußennachinnen(outermost-first):
inc (double ( inc 3)) →double (inc 3)+ 1
→2*(inc 3)+ 1
→2*(3+ 1)+ 1
→2*4+1→9 I Voninnennachaußen(innermost-first):
inc (double (inc 3)) →inc (double (3+1))
→inc (2*(3+ 1))
→(2*(3+ 1))+ 1
→2*4+1→9
Konfluenz und Termination
Sei→∗ die Reduktion in null oder mehr Schritten.
Definition (Konfluenz)
→∗ istkonfluentgdw:
Für aller,s,tmits←∗ r→∗ tgibt esuso dasss→∗ u←∗ t.
Definition (Termination)
→istterminierendgdw. es keine unendlichen Ketten gibt:
t1→t2→t3→. . .tn→. . .
Auswertungsstrategien
I Wenn wir von Laufzeitfehlern abstrahieren, gilt:
Theorem (Konfluenz)
Funktionale Programme sind für jede Auswertungsstrategiekonfluent.
Theorem (Normalform)
Terminierendefunktionale Programme werten unter jeder Auswertungsstragie jeden Ausdruck zum gleichen Wert aus (der Normalform).
I Auswertungsstrategie fürnicht-terminierendeProgramme relevant I Nicht-Terminationnötig(Turing-Mächtigkeit)
17 [38]
Auswirkung der Auswertungsstrategie
I Outermost-first entsprichtcall-by-need,verzögerteAuswertung.
I Innermost-first entsprichtcall-by-value,strikteAuswertung I Beispiel:
repeat :: Int→ String→ String repeat n s=i f n==0 then""
else s ++repeat (n−1) s undef :: String
undef=undef
I Auswertung von repeat 0 undef
18 [38]
Striktheit
Definition (Striktheit)
Funktionf iststrikt ⇐⇒ Ergebnis ist undefiniert
sobald ein Argument undefiniert ist.
I DenotationelleEigenschaft (nicht operational)
I Java, C etc. sindcall-by-value(nach Sprachdefinition) und damitstrikt I Haskell istnicht-strikt(nach Sprachdefinition)
I repeat0 undefmuss""ergeben.
I MeistenImplementationennutzenverzögerte Auswertung I Fallunterscheidung istimmernicht-strikt.
19 [38]
Datentypen
20 [38]
Datentypen als Modellierungskonstrukt
ProgrammemanipuliereneinModell(der Umwelt)
I FunktionaleSicht:
Werte Funktionen Werte
I ImperativeSicht: Speicher Programm
I ObjektorientierteSicht: Methoden
Objekte
Speicher Speicher
Speicher
21 [38]
Typkonstruktoren
I Aufzählungen
I Produkt
I Rekursion
I Funktionsraum
22 [38]
Beispiel: Uncle Bob’s Auld-Time Grocery Shoppe
Ein Tante-Emma Laden wie in früheren Zeiten.
23 [38]
Beispiel: Uncle Bob’s Auld-Time Grocery Shoppe
Äpfel Boskoop 55 ct/Stk
Cox Orange 60 ct/Stk Granny Smith 50 ct/Stk
Eier 20 ct/Stk
Käse Gouda 14,50 ¤/kg
Appenzeller 22.70 ¤/kg
Schinken 1.99 ¤/100 g
Salami 1.59 ¤/100 g
Milch 0.69 ¤/l
Bio 1.19 ¤/l
24 [38]
Aufzählungen
I Aufzählungen: Menge vondisjunktenKonstanten Apfel={Boskoop,Cox,Smith}
Boskoop6=Cox,Cox6=Smith,Boskoop6=Smith
I GenaudreiunterschiedlicheKonstanten
I Funktion mitWertebereichApfelmuss drei Fälle unterscheiden I Beispiel:preis:Apfel→Nmit
preis(a) =
55 a=Boskoop 60 a=Cox 50 a=Smith
25 [38]
Aufzählung und Fallunterscheidung in Haskell
I Definition
data Apfel=Boskoop | CoxOrange | GrannySmith
IImpliziteDeklarationderKonstruktorenBoskoop::Apfel alsKonstanten
IGroßschreibungder Konstruktoren I Fallunterscheidung:
apreis :: Apfel → Int apreis a=casea of
Boskoop→ 55 CoxOrange→ 60 GrannySmith→ 50
data Farbe=Rot | Grn farbe :: Apfel→ Farbe farbe d=
cased of
GrannySmith → Grn _→ Rot
26 [38]
Fallunterscheidung in der Funktionsdefinition
I Abkürzende Schreibweisen (syntaktischer Zucker):
f c1==e1 . . . f cn==en
−→
f x==casexofc1 → e1, . . . cn → en
I Damit:
apreis :: Apfel→ Int apreis Boskoop=55 apreis CoxOrange=60 apreis GrannySmith=50
27 [38]
Der einfachste Aufzählungstyp
I EinfachsteAufzählung: Wahrheitswerte Bool={True,False}
IGenau zwei unterschiedliche Werte I Definitionvon Funktionen:
IWertetabellensind explizite Fallunterscheidungen
∧ true false true true false false false false
true ∧ true = true true ∧ false = false false ∧ true = false false ∧ false = false
28 [38]
Wahrheitswerte: Bool
I Vordefiniertals
data Bool=True | False I VordefinierteFunktionen:
not :: Bool→ Bool −−Negation (&&) :: Bool→ Bool→ Bool −−Konjunktion
(| |) :: Bool→ Bool→ Bool −−Disjunktion I Konjunktiondefiniert als
a && b=casea of False → False True →b I &&,| |sind rechtsnicht strikt
I 1==0 && div 1 0==0 False
I if _then_else_ als syntaktischer Zucker:
ifbthenpelseq −→casebof True → p False → q
29 [38]
Beispiel: Ausschließende Disjunktion
I Mathematische Definiton:
exOr :: Bool→ Bool→Bool
exOr x y=(x | | y) && (not (x && y )) I Alternative 1:explizite Wertetabelle:
exOr False False=False exOr True False=True exOr False True =True exOr True True =False
I Alternative 2:Fallunterscheidungauf ersten Argument exOr True y=not y
exOr False y=y I Was ist ambesten?
IEffizienz, Lesbarkeit, Striktheit
30 [38]
Produkte
I Konstruktoren könnenArgumentehaben I Beispiel: EinDatumbesteht ausTag,Monat,Jahr I Mathematisch: Produkt (Tupel)
Date = {Date (n, m, y)|n∈N,m∈Month,y∈N} Month = {Jan,Feb,Mar, . . .}
I Funktionsdefinition:
I Konstruktorargumente sindgebundene Variablen year(D(n,m,y)) = y
day(D(n,m,y)) = n
I Bei derAuswertungwirdgebundene Variabledurchkonkretes Argument ersetzt
Produkte in Haskell
I Konstruktoren mitArgumenten dataDate =Date Int Month Int
dataMonth=Jan | Feb | Mar | Apr |May | Jun
| Jul | Aug | Sep | Oct | Nov | Dec I Beispielwerte:
today =Date 21 Oct 2014 bloomsday=Date 16 Jun 1904
I ÜberFallunterscheidungZugriff aufArgumenteder Konstruktoren:
day :: Date→ Int year :: Date→ Int
day d=casedof Date t m y→t year (Date d m y)=y
Beispiel: Tag im Jahr
I Tag im Jahr: Tag im laufenden Monat plus Summe der Anzahl der Tage der vorherigen Monate
yearDay :: Date→ Int
yearDay (Date d m y)=d+sumPrevMonths mwhere sumPrevMonths :: Month→ Int
sumPrevMonths Jan=0
sumPrevMonths m =daysInMonth ( prev m) y+ sumPrevMonths ( prev m) I Tage im Monat benötigt Jahr als Argument (Schaltjahr!)
daysInMonth :: Month→ Int→ Int prev :: Month→Month
I Schaltjahr: Gregorianischer Kalender leapyear :: Int→ Bool
leapyear y=i f mod y 100==0 thenmod y 400==0 elsemod y 4==0
33 [38]
Beispiel: Produkte in Bob’s Shoppe
I Käsesorten und deren Preise:
dataKaese=Gouda | Appenzeller kpreis :: Kaese → Double kpreis Gouda=1450 kpreis Appenzeller=2270 I Alle Artikel:
data A r t i k e l= Apfel Apfel | Eier
| Kaese Kaese | Schinken
| Salami | Milch Bool
34 [38]
Beispiel: Produkte in Bob’s Shoppe
I Mengenangaben:
dataMenge=Stueck Int | Gramm Int
| Kilo Double | L i t e r Double I Der Preis und seine Berechnung:
data Preis=Cent Int | Ungueltig p r e i s :: A r t i k e l →Menge→ Preis
p r e i s ( Apfel a) (Stueck n) =Cent (n∗ apreis a) p r e i s Eier (Stueck n) =Cent (n∗ 20) p r e i s (Kaese k)( Kilo kg) =Cent (round(kg∗
kpreis k)) p r e i s Schinken (Gramm g) =Cent (g/100∗ 199) p r e i s Salami (Gramm g) =Cent (g/100∗ 159) p r e i s (Milch bio ) ( L i t e r l )=
Cent (round ( l∗ i f not bio then 69 else 119))
p r e i s _ _ =Ungueltig
35 [38]
Auswertung der Fallunterscheidung
I Argument der Fallunterscheidung wirdnur soweit nötigausgewertet I Beispiel:
dataFoo=Foo Int | Bar f :: Foo→Int
f foo=casefoo ofFoo i → i ; Bar→0 g :: Foo→Int
g foo=casefoo ofFoo i →9; Bar →0 I Auswertungen:
f Bar → 0
f (Foo undefined) → ∗∗∗Exception: undefined
g Bar → 0
g (Foo undefined) → 9
36 [38]
Der Allgemeine Fall: Algebraische Datentypen
Definition einesalgebraischen DatentypenT:
data T= C1t1,1. . .t1,k1
. . .
| Cntn,1. . .tn,kn
I KonstruktorenC1, . . . ,Cnsinddisjunkt:
Cix1. . .xn=Cjy1. . .ym=⇒i=j I Konstruktorensindinjektiv:
C x1. . .xn=C y1. . .yn=⇒xi=yi I Konstruktorenerzeugenden Datentyp:
∀x∈T.x=Ciy1. . .ym Diese Eigenschaften machenFallunterscheidungmöglich.
Rekursion? Nächste Vorlesung!
37 [38]
Zusammenfassung
I Striktheit
IHaskell istspezifiziertals nicht-strikt I Datentypen und Funktionsdefinitiondual
IAufzählungen—Fallunterscheidung
IProdukte— Projektion I Algebraische Datentypen
IDreiwesentlicheEigenschaftender Konstruktoren I Nächste Vorlesung: Rekursive Datentypen
38 [38]