Die KFP-Kernsprachen

Werbung
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Übersicht
Einführung in die
Funktionale Programmierung:
1
Einleitung
2
KFPT
3
KFPTS
4
Erweiterung um seq
5
Polymorphe Typen
Funktionale Kernsprachen:
Die KFP-Kernsprachen
Prof. Dr. Manfred Schmidt-Schauß
WS 2011/12
Stand der Folien: 31. Oktober 2011
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
1
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
2/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Lambda-Kalkül und Haskell
Lambda-Kalkül und Haskell (2)
Der Lambda-Kalkül ist als Kernsprache für Haskell eher ungeeignet:
Keine echten Daten:
Zahlen, Boolesche Werte, Listen und komplexe
Datenstrukturen fehlen im Lambda-Kalkül.
Rekursive Funktionen: Geht nur über Fixpunkt-Kombinatoren:
Fakultät als Beispiel:
Ausweg Church-Kodierung:
f ak = (λf.(λx.f (x x)) (λx.f (x x)))
(λf.λx.if x = 0 then 1 else x ∗ (f (x − 1)))
z.B. true
= λx, y.x
false
= λx, y.y
if-then-else = λb, x1 , x2 .b x1 x2
Aber: Kompliziert und schwer verständlich!
if then-else true e1 e2 = (λb, x1 , x2 .b x1 x2 ) (λx, y.x) e1 e2
no,β,3
Typisierung fehlt Haskell ist polymorph getypt.
no,β,2
−−−−→ (λx, y.x) e1 e2 −−−−→ e1
Kein seq: In Haskell ist seq verfügbar, im Lambda-Kalkül
nicht kodierbar.
if then-else false e1 e2 = (λb, x1 , x2 .b x1 x2 ) (λx, y.y) e1 e2
no,β,3
no,β,2
−−−−→ (λx, y.y) e1 e2 −−−−→ e2
Aber: Kompliziert; Daten und Funktionen sind nicht
unterscheidbar; Typisierung passt nicht
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
3/54
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
4/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Kernsprachen für Haskell
Die Kernsprache KFPT
Im folgenden führen wir verschiedene Kernsprachen ein.
Alle sind Erweiterungen des Lambda-Kalküls
Erweiterung des Lambda-Kalküls um
Datentypen (Konstruktoren) und case.
Bezeichnungen: KFP. . .
KFPT: T steht für getyptes case
KFP = Kern einer Funktionalen Programmiersprache
Beachte: KFPT ist nur ganz schwach getypt.
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
5/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
6/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Datentypen
Syntax von KFPT
Annahmen:
Expr ::= V
| λV.Expr
| (Expr1 Expr2 )
| (ci Expr1 . . . Exprar(ci ) )
| (caseTypname Expr of
{Pat1 → Expr1 ; . . . ; Patn → Exprn })
Es gibt eine (endliche) Menge von Typen (das sind nur Namen)
Für jeden Typ gibt es eine endliche Menge von
Datenkonstruktoren: Formale Notation: ci .
Datenkonstruktoren haben eine Stelligkeit ar(ci ) ∈ N0
(ar = arity“)
”
Beispiele
(Variable)
(Abstraktion)
(Anwendung)
(Konstruktoranwendung)
(case-Ausdruck)
Pati ::= (ci V1 . . . Var (ci ) )
(Pattern für Konstruktor i)
wobei die Variablen Vi alle verschieden sind.
Typ Bool, Datenkonstruktoren: True und False,
ar(True) = 0 = ar(False).
Nebenbedingungen:
Typ List, Datenkonstruktoren: Nil und Cons,
ar(Nil) = 0 und ar(Cons) = 2.
case mit Typ gekennzeichnet,
Pati → Expri heißt case-Alternative
Haskell-Schreibweise: [] für Nil und : (infix) für Cons
case-Alternativen sind vollständig und disjunkt für den Typ:
für jeden Konstruktor des Typs kommt genau eine Alternative vor.
Beachte [a1 , a2 , . . . , an ] ist Abkürzung für a1 : (a2 : (. . . : (an : [])))
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
7/54
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
8/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Beispiele (1)
Beispiele (2)
Erstes Element einer Liste (head):
Paare: Typ Paar mit zweistelligem Konstruktor Paar
Z.B. wird (True, False) durch (Paar True False)
dargestellt.
λxs.caseList xs of {Nil → ⊥; (Cons y ys) → y}
Restliste ohne erstes Element (tail):
Projektionen:
λxs.caseList xs of {Nil → ⊥; (Cons y ys) → ys}
fst
snd
Test, ob Liste leer ist (null):
λxs.caseList xs of {Nil → True; (Cons y ys) → False}
Analog: mehrstellige Tupel
In Haskell sind Tupel bereits vorhanden (eingebaut),
Schreibweise (a1 , . . . , an )
if e then s else t:
In Haskell auch 0-stellige Tupel, keine 1-stelligen Tupel
caseBool e of {True → s; False → t}
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
:= λx.casePaar x of {(Paar a b) → a}
:= λx.casePaar x of {(Paar a b) → b}
9/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
10/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Haskell vs. KFPT: case-Ausdrücke (1)
Haskell vs. KFPT: case-Ausdrücke (2)
Vergleich mit Haskells case-Ausdrücken
Syntax ähnlich:
Haskell erlaubt überlappende Pattern. Z.B. ist
Statt → in Haskell: ->
Keine Typmarkierung am case
case [] of {[] -> []; (x:(y:ys)) -> [y]}
ein gültiger Haskell-Ausdruck
Beispiel:
Semikolon und Klammern kann man bei Einrückung
weglassen:
case [] of
[] -> []
(x:(y:ys)) -> [y]
KFPT: caseList xs of {(Nil → Nil; (y : ys) → y}
Haskell: case xs of {[] -> []; (y:ys) -> y}
In Haskell nicht notwendig alle Konstruktoren abzudecken
Kann Laufzeitfehler geben:
(case True of False -> False)
*** Exception: Non-exhaustive patterns in case
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
11/54
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
12/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Haskell vs. KFPT: case-Ausdrücke (3)
Freie und gebundene Variablen in KFPT
Übersetzung von geschachtelten in einfache Pattern (für KFPT)
case [] of {[] -> []; (x:(y:ys)) -> [y]}
wird übersetzt in:
Zusätzlich zum Lambda-Kalkül: In case-Alternative
caseList Nil of {Nil → Nil;
(Cons x z) → caseList z of {Nil → ⊥;
(Cons y ys) → (Cons y Nil)
}
}
(ci x1 . . . xar(ci ) ) → s
sind die Variablen x1 , . . . , xar(ci ) in s gebunden.
Fehlende Alternativen werden durch P at → ⊥ ergänzt.
⊥ (gesprochen als bot“): Repräsentant eines geschlossenen
”
nicht terminierenden Ausdrucks.
Abkürzung: (caseT yp s of Alts)
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
13/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
14/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Freie Variablen
Gebundene Variablen
FV (x)
FV (λx.s)
FV (s t)
FV (c s1 . . . sar(c) )
=x
= FV (s) \ {x}
= FV (s) ∪ FV (t)
= FV (s1 ) ∪ . . . ∪ FV (sar(ci ) )
n
S
FV (caseT yp t of
= FV (t) ∪ ( (FV (si ) \ {xi,1 , . . . , xi,ar(ci ) }))
i=1
{(c1 x1,1 . . . x1,ar(c1 ) ) → s1 ;
...
(cn xn,1 . . . xn,ar(cn ) ) → sn })
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
15/54
=∅
= BV (s) ∪ {x}
= BV (s) ∪ BV (t)
= BV (s1 ) ∪ . . . ∪ BV (sar(ci ) )
n
S
BV (caseT yp t of
= BV (t) ∪ ( (BV (si ) ∪ {xi,1 , . . . , xi,ar(ci ) }))
i=1
{(c1 x1,1 . . . x1,ar(c1 ) ) → s1 ;
...
(cn xn,1 . . . xn,ar(cn ) ) → sn })
BV (x)
BV (λx.s)
BV (s t)
BV (c s1 . . . sar(c) )
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
16/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Beispiel
Notationen
s := ((λx.caseList x of {Nil → x; Cons x xs → λu.(x λx.(x u))) x)}
FV (s) = {x} und BV (s) = {x, u}
Wie im Lambda-Kalkül (mit angepasster FV , BV Definition)
Offene und geschlossene Ausdrücke
Alpha-äquivalenter Ausdruck:
α-Umbenennung
Distinct Variable Convention
0
s := ((λx1 .caseList x1 of {Nil → x1 ; Cons x2 xs → λu.(x2 λx3 .(x3 u))) x)}
FV (s0 ) = {x} und BV (s0 ) = {x1 , x2 , x3 , u}
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
17/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
18/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Operationale Semantik
Beispiel
Substitution
s[t/x] ersetzt alle freien Vorkommen von x in s durch t
(wenn BV (s) ∩ FV (t) = ∅)
s[t1 /x1 , . . . , tn /xn ] parallele Ersetzung von x1 , . . . , xn durch
t1 , . . . , tn (wenn für alle i:BV (s) ∩ FV (ti ) = ∅)
(λx.casePaar x of {(Paar a b) → a}) (Paar True False)
β
−
→
Definition
Die Reduktionsregeln (β) und (case) sind in KFPT definiert als:
(β)
casePaar (Paar True False) of {(Paar a b) → a}
case
−−→ True
(λx.s) t → s[t/x]
(case) caseT yp (c s1 . . . sar(c) ) of {. . . ; (c x1 . . . xar(c) ) → t; . . .}
→ t[s1 /x1 , . . . , sar(c) /xar(c) ]
Wenn s → t mit (β) oder (case) dann reduziert s unmittelbar zu t
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
19/54
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
20/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Kontexte
Normalordnungsreduktion
Definition
Reduktionskontexte R in KFPT werden durch die folgende
Grammatik erzeugt:
Kontext = Ausdruck mit Loch [·]
C ::= [·] | λV.C | (C Expr) | (Expr C)
| (ci Expr1 . . . Expri−1 C Expri+1 Exprar(ci ) )
| (caseTyp C of {Pat1 → Expr1 ; . . . ; Patn → Exprn })
| (caseTyp Expr of {Pat1 → Expr1 ; . . . ; Pati → C; . . . , Patn → Exprn })
β
case
Wenn C[s] → C[t] wobei s −
→ t oder s −−→ t, dann bezeichnet
man s (mit seiner Position in C) als Redex von C[s].
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
21/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
22/54
Beispiele
Definition
Wenn s unmittelbar zu t reduziert, dann ist R[s] → R[t] für jeden
Reduktionskontext R eine Normalordnungsreduktion.
no,β
(λx.x) ((λy.y) (λz.z)) → (λy.y) (λz.z) ist eine
Normalordnungsreduktion.
(λx.x) ((λy.y) (λz.z)) → (λx.x) (λz.z) ist keine
Normalordnungsreduktion
no,case
Notation: −→, bzw. auch −−−→ und −−−−→.
no
−−−→ transitive Hülle von −→
no,∗
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Normalordnungsreduktion (2)
no,+
Redexsuche mit ∗
Neue Regel:
• (caseT yp s of Alts)? ⇒ (caseT yp s? of Alts)
Beispiel:
((caseBool s of {True → (λx, y.x); False → (λx, y.y)}) Nil)?
Redex = Reducible expression
no
R ::= [·] | (R Expr) | (caseT yp R of Alts)
no
−−→ reflexiv-transitive Hülle von −→
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
23/54
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
24/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Normalformen
Terminierung bzw. Konvergenz
Ein KFPT-Ausdruck s ist eine
Normalform (NF = normal form):
s enthält keine (β)- oder (case)-Redexe ist WHNF
Kopfnormalform (HNF = head normal form):
s ist Konstruktoranwendung oder Abstraktion λx1 , . . . xn .s0 , wobei s0
entweder Variable oder (c s1 . . . sar(c) ) oder (x s0 ) ist
schwache Kopfnormalform (WHNF = weak head normal form):
s ist eine FWHNF oder eine CWHNF.
funktionale schwache Kopfnormalform (FWHNF = functional whnf):
s ist eine Abstraktion
Konstruktor-schwache Kopfnormalform (CWHNF = constructor whnf):
s ist eine Konstruktoranwendung (c s1 . . . sar(c) )
Wir verwenden nur WHNFs (keine NFs, keine HNFs).
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
25/54
Definition
Ein KFPT-Ausdruck s konvergiert (oder terminiert, notiert als s ⇓)
genau dann, wenn:
no,∗
s ⇓ ⇐⇒ ∃ WHNF t : s −−→ t
Falls s nicht konvergiert, so sagen wir s divergiert und notieren
dies mit s ⇑.
Sprechweisen:
Wir sagen s hat eine WHNF (bzw. FWHNF, CWHNF),
no,∗
wenn s zu einer WHNF (bzw. FWHNF, CWHNF) mit −−→
reduziert werden kann.
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
26/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Dynamische Typisierung
Beispiele
Normalordnungsreduktion stoppt ohne WHNF: Folgende Fälle
Eine freie Variable wurde gefunden (Ausdruck von der Form R[x]),
oder
Ein dynamischer Typfehler tritt auf.
caseList True of {Nil → Nil; (Cons x xs) → xs}
ist direkt dynamisch ungetypt
Definition (Dynamische Typregeln für KFPT)
(λx.caseList x of {Nil → Nil; (Cons x xs) → xs}) True
ist dynamisch ungetypt
Ein KFPT-Ausdruck s direkt dynamisch ungetypt, falls:
(Cons True Nil) (λx.x) ist direkt dynamisch ungetypt
s = R[caseT (c s1 . . . sn ) of Alts] und c ist nicht vom Typ T
(caseBool x of {True → True; False → False})
ist nicht (direkt) dynamisch ungetypt
s = R[caseT λx.t of Alts].
(λx.caseBool x of {True → True; False → False}) (λy.y)
ist dynamisch ungetypt
s = R[(c s1 . . . sar(c) ) t]
s ist dynamisch ungetypt
⇐⇒
no,∗
∃t : s −−→ t ∧ t ist direkt dynamisch ungetypt
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
27/54
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
28/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Dynamische Typisierung (2)
Markierungsalgorithmus zur NO-Redex-Suche
Für Ausdruck s starte mit s? , Verschieberegeln:
(s t)? ⇒ (s? t)
(caseT yp s of Alts)? ⇒ (caseT yp s? of Alts)
Satz
Ein geschlossener KFPT-Ausdruck s ist irreduzibel (bzgl. der
Normalordnung) genau dann, wenn eine der folgenden
Bedingungen auf ihn zutrifft:
Fälle danach:
Markierung ist an einer Abstraktion; Fälle:
(λx.s0 )? , dann FWHNF
C[((λx.s0 )? s00 )], dann reduziere die Applikation mit β
C[caseT (λx.s0 )? . . .)], dann direkt dynamisch ungetypt
Entweder ist s eine WHNF, oder
Markierung ist an einer Konstruktorapplikation
s ist direkt dynamisch ungetypt.
(c . . .)? , dann CWHNF
C[((c . . .)? s0 )], dann direkt dynamisch ungetypt
C[(caseT (c . . .)? alts)], reduzieren, falls c zum Typ T
gehört, sonst direkt dynamisch ungetypt
Markierung ist an einer Variablen: Keine Reduktion möglich
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
29/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Darstellung von Ausdrücken als Termgraphen
0
1
caseList y of {
A True)) (λu, v.v)) (Cons (λw.w) Nil))?
(((λx.λy.(@ Nil → Nil;
(Cons z zs) → (x z)}
−−−→
no,β
−−−→
Knoten für je ein syntaktisches Konstrukt des Ausdrucks
Variablen = ein Blatt
0
1
caseList y of {
A True)) (Cons (λw.w) Nil))?
((λy.(@ Nil → Nil;
(Cons z zs) → ((λu, v.v) z)}
Abstraktionen λx.s
0
1
caseList (Cons (λw.w) Nil) of {
A True)?
(@ Nil → Nil;
(Cons z zs) → ((λu, v.v) z)}
no,case
x
Applikationen (s t)

no,β
no,β
−−−→
s
((λv.v) True)?
λ?
wobei s Baum für s
??
??
??
s
@>
?
−−−−−→ (((λu, v.v) (λw.w)) True)
−−−→
30/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Beispiel
no,β
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
wobei s , t Bäume für s und t
>>
>>
>>
t
True
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
31/54
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
32/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Darstellung von Ausdrücken als Termgraphen (2)
Beispiel
Konstruktoranwendungen n-stellig: (c s1 . . . sn )
wobei si die Bäume für si
mm c QBBQQ
m |
BBQQQQ
mmm ||
BB QQQQ
mmm |||
m
BB
QQQ
m
m
|
m
BB
QQ(
||
m
v mm
|
~
...
...
...
s1
sn



λx.λy.caseList (Cons x Nil) of {

(Cons z zs) → False;  True (Cons True Nil)
Nil → True}
hhhh @ SSSS
case-Ausdrücke: n + 1 Kinder, caseT yp s of {Alt1 ; . . . ; Altn }
caseT yp
GGRRR
kt
GG RRRR
kkktkttt
k
GG
k
k
k
t
k
GG RRRRRR
k
t
t
kk
GG
RRR
k
t
z
k
k
)
G#
u kk
k
...
...
s
Alt1
Altn
→@
case-Alternative P at → t
yy
yy
y
y
y| y
@@
@@
@@
@
x
t
P at
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
33/54
False Nil
True
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
34/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Normalordnungsreduktion: Eigenschaften
Rekursive Superkombinatoren: KFPTS
Die Normalordnungsreduktion ist deterministisch, d.h. für
no
jedes s gibt es höchstens ein t mit s −→ t.
Eine WHNF ist irreduzibel bezüglich der
Normalordnungsreduktion.
Nächste Erweiterung: KFPT zu KFPTS
S“ steht für Superkombinatoren
”
Superkombinatoren sind Namen (Konstanten) für Funktionen
Theorem (Standardisierung für KFPT)
Superkombinatoren dürfen auch rekursive Funktionen sein
∗
Wenn s →
− t mit beliebigen (β)- und (case)-Reduktionen (in
beliebigem Kontext angewendet), wobei t eine WHNF ist, dann
no,∗
∗
existiert eine WHNF t0 , so dass s −−→ t0 und t0 →
− t.
Annahme: Es gibt eine Menge von Superkombinatornamen SK.
Beispiel: Superkombinator length
s@
@ no,∗
~~
~
@
~
~
@
~ ~
_
o
_
_
_
_
_
t
t0
∗
length xs =caseList xs of {
Nil → 0;
(Cons y ys) → (1 + length ys)}
∗
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
Nil Cons OO
u
OOO
'
u
z uu
z
zs
NO-Redex-Suche: immer links, bis Abstraktion, Konstruktoranwendung
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
WHNF
h
SSS
hhhh
S)
thhhh
ConsGG
O
i
@
i
O
i
O
i
u
OOO
GG
iiii
'
zuuu
#
tiiii
True
True
Nil
λ
G
G
GGG
ww
#
{www
x
w λ NNNNN
w
w
N&
{ww
y
caseList XXX
f
f
XXXXXX
f
f
ffff
XXXXXX
rfffff
,→
→
ConsH
O
OOO
v JJJJ
pp
HH
|
v
p
v
O
|
p
v
#
wp
'
{
$
}|
WHNF
35/54
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
36/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
KFPTS: Syntax
KFPTS:Syntax (2)
Zu jedem Superkombinator gibt es eine Superkombinatordefinition:
Expr ::=
|
|
|
V | λV.Expr | (Expr1 Expr2 )
(ci Expr1 . . . Exprar(ci ) )
(caseTyp Expr of {Pat1 → Expr1 ; . . . ; Patn → Exprn })
SK wobei SK ∈ SK
SK V1 . . . Vn = Expr
dabei
Vi paarweise verschiedene Variablen;
Expr ein KFPTS-Ausdruck;
Pati ::= (ci V1 . . . Var (ci ) ) wobei die Variablen Vi alle verschieden sind.
FV (Expr) ⊆ {V1 , . . . , Vn };
ar(SK) = n ≥ 0: Stelligkeit des Superkombinators
(n = 0 ist möglich).
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
37/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
38/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
KFPTS: Syntax (3)
KFPTS: Operationale Semantik
Reduktionskontexte:
R ::= [·] | (R Expr) | caseT yp R of Alts
Ein KFPTS-Programm besteht aus:
Reduktionsregeln (β), (case) und (SK-β):
Einer Menge von Typen und Konstruktoren,
einer Menge von Superkombinator-Definitionen,
und aus einem KFPTS-Ausdruck s.
(Diesen könnte man auch als Superkombinator main mit
Definition main = s definieren.)
(β)
(λx.s) t → s[t/x]
(case)
caseT yp (c s1 . . . sar(c) ) of {. . . ; (c x1 . . . xar(c) ) → t; . . .}
→ t[s1 /x1 , . . . , sar(c) /xar(c) ]
(SK-β) (SK s1 . . . sn ) → e[s1 /x1 , . . . , s2 /xn ],
wenn SK x1 . . . xn = e die Definition von SK ist
Dabei müssen alle in s verwendeten Superkombinatoren auch
definiert sein.
Normalordnungsreduktion:
s → t mit (β)-, (case)- oder (SK-β)
no
R[s] −→ R[t]
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
39/54
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
40/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
KFPTS: WHNFs und Dynamische Typisierung
Markierungsalgorithmus
WHNFs
Markierung funktioniert genauso wie in KFPTS:
WHNF = CWHNF oder FWHNF
(s t)? ⇒ (s? t)
CWHNF = Konstruktoranwendung (c s1 . . . sar(c) )
(caseT yp s of Alts)? ⇒ (caseT yp s? of Alts)
FWHNF = Abstraktion oder SK s1 . . . sm mit ar(SK) > m
Neue Fälle:
Ein Superkombinator ist mit ? markiert:
Direkt dynamisch ungetypt:
Regeln wie vorher: R[(caseT λx.s of . . .)],
R[(caseT (c s1 . . . sn )of . . .)], wenn c nicht von Typ T und
R[((c s1 . . . sar(c) ) t)]
Genügend Argumente vorhanden: Reduziere mit (SK-β)
Zu wenig Argumente und kein Kontext außen: WHNF
Zu wenig Argumente und im Kontext (case [.] . . .): direkt
dynamisch ungetypt.
Neue Regel: R[caseT (SK s1 . . . sm ) of Alts] ist direkt
dynamisch ungetypt falls ar(SK) > m.
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
41/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
42/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Beispiel
Erweiterung um seq und strict
Die Superkombinatoren map und not seien definiert als:
map f xs = caseList xs of {Nil → Nil;
(Cons y ys) → Cons (f y) (map f ys)}
not x
= caseBool x of {True → False; False → True}
In Haskell gibt es seq:
½
(seq a b) =
b falls a ⇓
⊥ falls a ⇑
Operational: Werte erst a aus, dann b
Beispiel zur Auswertung:
Analog: strict (in Haskell infix als $! geschrieben)
map not (Cons True (Cons False Nil))
strict f macht f strikt im ersten Argument, d.h. strict f
wertet erst das Argument aus, dann erfolgt die
Definitionseinsetzung.
no,SK-β
−−−−−→ caseList (Cons True (Cons False Nil)) of {
Nil → Nil;
(Cons y ys) → Cons (not y) (map not ys)}
no,case
−−−−→ Cons (not True) (map not (Cons False Nil))
seq und strict sind austauschbar:
f $! x
seq a b
WHNF erreicht!
=
=
seq x (f x)
(\x -> b) $! a
Beachte: Im GHCI-Interpreter wird nur aufgrund des Anzeigens weiter
ausgewertet
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
43/54
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
44/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
KFPXX+seq Sprachen
Bemerkung: Die Sprache KFP
KFP hat keine Typbeschränkungen!
seq ist in KFPT, KFPTS nicht kodierbar!
Expr ::= V | λV.Expr | (Expr1 Expr2 )
| (ci Expr1 . . . Exprar(ci ) )
| (case Expr of
{Pat1 → Expr1 ; . . . ; Patn → Exprn ; lambda → Exprn+1 })
wobei P at1 , . . . , P atn alle Konstruktoren abdecken
Wir bezeichnen mit
KFPT+seq die Erweiterung von KFPT um seq
KFPTS+seq die Erweiterung von KFPTS um seq
Wir verzichten auf die formale Definition!
Man benötigt u.a. die Reduktionsregel:
Pati
seq v t → t, wenn v WHNF
::= (ci V1 . . . Var (ci ) ) wobei die Variablen Vi alle verschieden sind.
Unterschied zu KFP: Kein getyptes case, lambda-Pattern
Neue Reduktionsregel case λx.s of {. . . , lambda → t} → t
erweiterte Reduktionskontexte und die neue Verschieberegel:
In KFP ist seq kodierbar:
(seq s t)? → (seq s? t)
seq a b := case a of {P at1 → b; . . . ; P atn → b; lambda → b}
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
45/54
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
46/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
KFPTSP
Beispiele
Mit KFPTSP bezeichnen wir polymorph getyptes KFPTS
Definition
Die Syntax von polymorphen Typen kann durch die folgende
Grammatik beschrieben werden:
True
False
not
map
(λx.x)
T ::= T V | T C T1 . . . Tn | T1 → T2
wobei T V für eine Typvariable steht und T C ein Typkonstruktor
mit Stelligkeit n ist.
::
::
::
::
::
Bool
Bool
Bool → Bool
(a → b) → [a] → [b]
(a → a)
polymorph: Typen haben Typvariablen
z.B. fak :: Int → Int
z.B. map :: (a → b) → (List a) → (List b)
Haskell: -> statt →
Haskell verwendet [a] statt (List a).
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
47/54
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
48/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Einfache Typregeln
Beispiel
Für die Anwendung:
s :: T1 → T2 , t :: T1
and := λx, y.caseBool x of {True → y; False → False}
or := λx.y.caseBool x of {True → True; False → y}
(s t) :: T2
Instantiierung
Mit der Anwendungsregel:
wenn T 0 = σ(T ), wobei σ eine Typsubstitution ist,
s :: T die Typen für Typvariablen ersetzt.
s :: T
and :: Bool → Bool → Bool, True :: Bool
0
(and True) :: Bool → Bool
(and True False) :: Bool
Für case-Ausdrücke:
s :: T1 ,
, False :: Bool
∀i : P ati :: T1 ,
∀i : ti :: T2
(caseT s of {P at1 → t1 ; . . . ; P atn → tn ) :: T2 }
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
49/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
50/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Beispiel
Beispiel
Cons :: a → [a] → [a]
Cons :: Bool → [Bool] → [Bool]
True :: Bool,
,
False :: Bool
, True :: Bool
(Cons True) :: [Bool] → [Bool]
(Cons True Nil) :: [Bool]
,
map :: (a → b) → [a] → [b]
Nil :: [a]
Nil :: [Bool]
,
Nil :: [a]
Nil :: [Bool]
caseBool True of {True → (Cons True Nil); False → Nil} :: [Bool]
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
51/54
map :: (Bool → Bool) → [Bool] → [Bool]
, not :: Bool → Bool
(map not) :: [Bool] → [Bool]
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
52/54
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Einleitung KFPT KFPTS Erweiterung um seq Polymorphe Typen
Ausblick
Übersicht
Kernsprache
KFP
KFPT
KFPTS
KFPTSP
KFPT+seq
KFPTS+seq
KFPTSP+seq
Besonderheiten
Erweiterung des call-by-name Lambda-Kalküls
um ungetyptes case und Datenkonstruktoren,
spezielles case-Pattern lambda ermöglicht Kodierung von seq.
Erweiterung des call-by-name Lambda-Kalküls
um (schwach) getyptes case und Datenkonstruktoren, seq ist nicht kodierbar.
Erweiterung von KFPT um rekursive Superkombinatoren, seq nicht kodierbar.
KFPTS, polymorph getypt; seq nicht kodierbar.
Erweiterung von KFPT um den seq-Operator
Erweiterung von KFPTS um den seq-Operator
KFPTSP+seq mit polymorpher Typisierung,
geeignete Kernsprache für Haskell
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
Erörterung der meisten Konstrukte von Haskell
insbesondere auch: Modulsystem, Typklassen
Informell: KFPTSP+seq ist die passende Kernsprache
Genaue Analyse der Typisierung kommt erst danach!
53/54
EFP – (04) Die KFP-Kernsprachen – WS 2011/12 – M. Schmidt-Schauß
54/54
Herunterladen