Phantom Types

Werbung
Phantom Types
Fabian Franzelin
Einführung
Motivation
Haskell
Phantom Types
Hauptseminar
Having Fun With Types
Phantom Types
Beispiel - Die Peanozahlen
Weitere
Anwendungsmöglichkeiten
C-style printf in Haskell
Typrepräsentanten und
dynamische Werte
Dynamisches Type-checking
Fabian Franzelin
Technische Universität München
22.06.2011
Zusammenfassung
Outline
Phantom Types
Fabian Franzelin
Einführung
Einführung
Motivation
Haskell
Motivation
Haskell
Phantom Types
Beispiel - Die Peanozahlen
Weitere
Anwendungsmöglichkeiten
Phantom Types
Beispiel - Die Peanozahlen
C-style printf in Haskell
Typrepräsentanten und
dynamische Werte
Dynamisches Type-checking
Zusammenfassung
Weitere Anwendungsmöglichkeiten
C-style printf in Haskell
Typrepräsentanten und dynamische Werte
Dynamisches Type-checking
Zusammenfassung
Outline
Phantom Types
Fabian Franzelin
Einführung
Einführung
Motivation
Haskell
Motivation
Haskell
Phantom Types
Beispiel - Die Peanozahlen
Weitere
Anwendungsmöglichkeiten
Phantom Types
Beispiel - Die Peanozahlen
C-style printf in Haskell
Typrepräsentanten und
dynamische Werte
Dynamisches Type-checking
Zusammenfassung
Weitere Anwendungsmöglichkeiten
C-style printf in Haskell
Typrepräsentanten und dynamische Werte
Dynamisches Type-checking
Zusammenfassung
Motivation - Typen, Werte und Ausdrücke
Phantom Types
Fabian Franzelin
Einführung
Motivation
Haskell
Phantom Types
Beispiel - Die Peanozahlen
Wert
gehört zu
Typ
Weitere
Anwendungsmöglichkeiten
C-style printf in Haskell
Typrepräsentanten und
dynamische Werte
Dynamisches Type-checking
Zusammenfassung
evaluiert zu
hat einen
Ausdruck
Quelle: vgl. Kreiker (2010), S. 2
Motivation - Typen, Werte und Ausdrücke
Phantom Types
Fabian Franzelin
Einführung
Motivation
Haskell
Phantom Types
Umsetzung?
Wert
gehört zu
Beispiel - Die Peanozahlen
Typ
Weitere
Anwendungsmöglichkeiten
C-style printf in Haskell
Typrepräsentanten und
dynamische Werte
Dynamisches Type-checking
Zusammenfassung
evaluiert zu
hat einen
Ausdruck
Quelle: vgl. Kreiker (2010), S. 2
Motivation - Typen, Werte und Ausdrücke
Phantom Types
Fabian Franzelin
Einführung
Motivation
Haskell
Phantom Types
Umsetzung?
Wert
gehört zu
Beispiel - Die Peanozahlen
Typ
Weitere
Anwendungsmöglichkeiten
C-style printf in Haskell
Typrepräsentanten und
dynamische Werte
Dynamisches Type-checking
Zusammenfassung
Semantik?
evaluiert zu
hat einen
Ausdruck
Quelle: vgl. Kreiker (2010), S. 2
Phantom Types
Haskell - Einführung
Fabian Franzelin
Einführung
Motivation
Typen und Werte
Haskell
Phantom Types
Ein Typ wird zusammen mit den
dazugehörigen Werten erstellt mit Hilfe
des data Konstrukts
Typ
Beispiel - Die Peanozahlen
Weitere
Anwendungsmöglichkeiten
C-style printf in Haskell
Unterscheidung Typkonstruktor,
Wertkonstruktor und Typvariable
Typrepräsentanten und
dynamische Werte
Dynamisches Type-checking
gehört zu
Beispiel
data T a = K1 | K2 a | K3 a a
K 1 :: T a
K 2 :: a → T a
K 3 :: a → a → T a
Wert
Zusammenfassung
Phantom Types
Haskell - Einführung
Fabian Franzelin
Einführung
Motivation
Typen und Werte
Haskell
Phantom Types
Ein Typ wird zusammen mit den
dazugehörigen Werten erstellt mit Hilfe
des data Konstrukts
Typ
Beispiel - Die Peanozahlen
Weitere
Anwendungsmöglichkeiten
C-style printf in Haskell
Unterscheidung Typkonstruktor,
Wertkonstruktor und Typvariable
Typrepräsentanten und
dynamische Werte
Dynamisches Type-checking
gehört zu
Beispiel
data T a = K1 | K2 a | K3 a a
K 1 :: T a
K 2 :: a → T a
K 3 :: a → a → T a
Wert
Zusammenfassung
Phantom Types
Haskell - Einführung
Fabian Franzelin
Einführung
Motivation
Typen und Werte
Haskell
Phantom Types
Ein Typ wird zusammen mit den
dazugehörigen Werten erstellt mit Hilfe
des data Konstrukts
Typ
Beispiel - Die Peanozahlen
Weitere
Anwendungsmöglichkeiten
C-style printf in Haskell
Unterscheidung Typkonstruktor,
Wertkonstruktor und Typvariable
Typrepräsentanten und
dynamische Werte
Dynamisches Type-checking
gehört zu
Beispiel
data T a = K1 | K2 a | K3 a a
K 1 :: T a
K 2 :: a → T a
K 3 :: a → a → T a
Wert
Zusammenfassung
Phantom Types
Haskell - Einführung
Fabian Franzelin
Einführung
Motivation
Typen und Werte
Haskell
Phantom Types
Ein Typ wird zusammen mit den
dazugehörigen Werten erstellt mit Hilfe
des data Konstrukts
Typ
Beispiel - Die Peanozahlen
Weitere
Anwendungsmöglichkeiten
C-style printf in Haskell
Unterscheidung Typkonstruktor,
Wertkonstruktor und Typvariable
Typrepräsentanten und
dynamische Werte
Dynamisches Type-checking
gehört zu
Beispiel
data T a = K1 | K2 a | K3 a a
K 1 :: T a
K 2 :: a → T a
K 3 :: a → a → T a
Wert
Zusammenfassung
Phantom Types
Haskell - Einführung cont
Fabian Franzelin
Einführung
Motivation
Dynamische Werte
Haskell
Phantom Types
Der Rückgabewert einer Funktion ist
dynamisch
Wert
Beispiel - Die Peanozahlen
Weitere
Anwendungsmöglichkeiten
C-style printf in Haskell
Typrepräsentanten und
dynamische Werte
Beispiele
Dynamisches Type-checking
(+) :: (Num t ) ⇒ t → t → t
evaluiert zu
(+) 1 2 = 3
(+) 1.2 3 = 4.2
Ausdruck
Zusammenfassung
Phantom Types
Haskell - Einführung cont
Fabian Franzelin
Einführung
Motivation
Statische Typen
Haskell
Phantom Types
Der Rückgabewert einer Funktion hat
immer denselben Typ bei gleicher
initialer Belegung
Typ
Beispiel - Die Peanozahlen
Weitere
Anwendungsmöglichkeiten
C-style printf in Haskell
Typrepräsentanten und
dynamische Werte
Dynamisches Type-checking
Beispiele
hat einen
(+) :: (Num t ) ⇒ t → t → t
(+) 1 2 = 3 :: (Num t ) ⇒ t
(+) 1.2 3 = 4.2 :: (Fractional t ) ⇒ t
Ausdruck
Zusammenfassung
Herausforderung
Phantom Types
Fabian Franzelin
Einführung
Motivation
Haskell
Phantom Types
Beispiel - Die Peanozahlen
Ziel
Weitere
Anwendungsmöglichkeiten
C-style printf in Haskell
Dynamische Typisierung mit generischer Programmierung im
Kontext einer statisch typisierten Umgebung einfach zu
ermöglichen.
Typrepräsentanten und
dynamische Werte
Dynamisches Type-checking
Zusammenfassung
Outline
Phantom Types
Fabian Franzelin
Einführung
Einführung
Motivation
Haskell
Motivation
Haskell
Phantom Types
Beispiel - Die Peanozahlen
Weitere
Anwendungsmöglichkeiten
Phantom Types
Beispiel - Die Peanozahlen
C-style printf in Haskell
Typrepräsentanten und
dynamische Werte
Dynamisches Type-checking
Zusammenfassung
Weitere Anwendungsmöglichkeiten
C-style printf in Haskell
Typrepräsentanten und dynamische Werte
Dynamisches Type-checking
Zusammenfassung
Beispiel - Die Peanozahlen
Definition
Phantom Types
Fabian Franzelin
Einführung
Motivation
Die Peanozahlen definieren die Menge der natürlichen Zahlen:
Haskell
Phantom Types
0∈N
Beispiel - Die Peanozahlen
n ∈ N ⇒ n − 1 ∈ N für n > 0
Weitere
Anwendungsmöglichkeiten
C-style printf in Haskell
Semantik: Peanozahlen mit If-Abfrage
Typrepräsentanten und
dynamische Werte
Dynamisches Type-checking
Zusammenfassung
Zero
:: Term Int
Succ
:: Term Int → Term Int
Pred
:: Term Int → Term Int
IsZero
:: ∀t .Term t → Term Bool
If
:: ∀t .Term Bool → Term t → Term t → Term t
Beispiel - Die Peanozahlen
Implementierung
Phantom Types
Fabian Franzelin
Einführung
Motivation
Haskell
Phantom Types
data Term t where
Beispiel - Die Peanozahlen
Zero
:: (t ~ Int) => Term Int
Succ
:: (t ~ Int) => (Term Int) -> Term Int
Pred
:: (t ~ Int) => (Term Int) -> Term Int
Weitere
Anwendungsmöglichkeiten
C-style printf in Haskell
Typrepräsentanten und
dynamische Werte
Dynamisches Type-checking
IsZero :: (t ~ Bool) => (Term Int) -> Term Bool
If
:: (t ~ a) => (Term Bool) -> (Term a) ->
(Term a) -> Term a
Zusammenfassung
Beispiel - Die Peanozahlen → Pantom Types
Implementierung
Phantom Types
Fabian Franzelin
Einführung
Motivation
Haskell
Phantom Types
data Term t where
Beispiel - Die Peanozahlen
Zero
:: (t ~ Int) => Term Int
Succ
:: (t ~ Int) => (Term Int) -> Term Int
Pred
:: (t ~ Int) => (Term Int) -> Term Int
Weitere
Anwendungsmöglichkeiten
C-style printf in Haskell
Typrepräsentanten und
dynamische Werte
Dynamisches Type-checking
IsZero :: (t ~ Bool) => (Term Int) -> Term Bool
If
:: (t ~ a) => (Term Bool) -> (Term a) ->
(Term a) -> Term a
Definition
Als Phantom Types werden parametrisierte Typen bezeichnet,
die ihre Typargumente nicht verwenden [Cheney, Hinze (2003)]
Zusammenfassung
Beispiel - Die Evaluierungsfunktion
Implementierung
Phantom Types
Fabian Franzelin
Einführung
Motivation
Haskell
eval :: ∀t .Term t → t
Phantom Types
Beispiel - Die Peanozahlen
Weitere
Anwendungsmöglichkeiten
eval Zero = 0
C-style printf in Haskell
eval (Succ a) = eval a + 1
eval (Pred a) = eval a - 1
Typrepräsentanten und
dynamische Werte
Dynamisches Type-checking
Zusammenfassung
eval (IsZero a) = eval a == 0
eval (If a b c) = if eval a then eval b
else eval c
Beispiele
eval (Succ (Succ Zero)) ⇒ 2
eval (IsZero (Succ Zero)) ⇒ False
eval (If (IsZero Zero) (Succ Zero) Zero) ⇒ 1
Outline
Phantom Types
Fabian Franzelin
Einführung
Einführung
Motivation
Haskell
Motivation
Haskell
Phantom Types
Beispiel - Die Peanozahlen
Weitere
Anwendungsmöglichkeiten
Phantom Types
Beispiel - Die Peanozahlen
C-style printf in Haskell
Typrepräsentanten und
dynamische Werte
Dynamisches Type-checking
Zusammenfassung
Weitere Anwendungsmöglichkeiten
C-style printf in Haskell
Typrepräsentanten und dynamische Werte
Dynamisches Type-checking
Zusammenfassung
C-style printf
Funktionssignatur
Phantom Types
Fabian Franzelin
Einführung
Motivation
Haskell
Phantom Types
int printf (const char* format, . . . )
Beispiel - Die Peanozahlen
Weitere
Anwendungsmöglichkeiten
C-style printf in Haskell
printf ist eine Ausgabefunktion in C
Typrepräsentanten und
dynamische Werte
Dynamisches Type-checking
Der Eingabestring beinhaltet normalen Text und spezielle
Tags
Die Tags markieren den Typ des Wertes, der an der
entsprechenden Stelle in die Ausgabe übernommen
werden soll
Diese Werte werden als weitere Parameter an printf
übergeben
Zusammenfassung
C-style printf cont
Beispiele
Phantom Types
Fabian Franzelin
Einführung
Motivation
Haskell
printf(“Hallo, mein Name ist %s”,
“Fabian”);
⇒ “Hallo, mein Name ist Fabian”
printf(“Ich b%cn %d Jahre und %i
Stunden alt”, ’i’, 27, 12.12);
⇒ “Ich bin 23 Jahre und -1546188227 Stunden alt”
Schwierigkeiten
1
Unendliche Menge an Eingabeparametern notwendig, die
allesamt unterschiedlichen Typs sein können
2
Dynamisches Type-checking und Casting
Phantom Types
Beispiel - Die Peanozahlen
Weitere
Anwendungsmöglichkeiten
C-style printf in Haskell
Typrepräsentanten und
dynamische Werte
Dynamisches Type-checking
Zusammenfassung
Phantom Types
(1) Typrepräsentanten
Fabian Franzelin
Man definiert sich Typrepräsentanten als Phantom Type,
die stellvertretend für jeweils einen Tag stehen, der über
printf ausgegeben werden kann
Einführung
Motivation
Haskell
Phantom Types
Beispiel - Die Peanozahlen
Tag
Repräsentant
Typ
%i
RInt
Int
%c
RChar
Char
%l
RList
∀a. [a]
%t
RPair
∀a, b. (a, b)
Weitere
Anwendungsmöglichkeiten
C-style printf in Haskell
Typrepräsentanten und
dynamische Werte
Dynamisches Type-checking
Man definiert sich einen Typ der Werte mit dem
dazugehörigen Typrepräsentant kapselt
Dynamic :: Typrepr äsentant → Wert → Dynamic
Zusammenfassung
(1) Typrepräsentanten cont
Implementierung der Typrepräsentanten
Phantom Types
Fabian Franzelin
Einführung
Motivation
Haskell
data Type t where
RInt
Phantom Types
:: (t ~ Int) => Type Int
RChar :: (t ~ Char) => Type Char
RList :: (t ~ [a]) => (Type a) -> Type [a]
Beispiel - Die Peanozahlen
Weitere
Anwendungsmöglichkeiten
C-style printf in Haskell
Typrepräsentanten und
dynamische Werte
RPair :: (t ~ (a, b)) => (Type a) -> (Type b) ->
Type (a, b)
RDyn
:: Type Dynamic
data Dynamic where Dyn :: Type t -> t -> Dynamic
Hinweis
Man beachte die zirkuläre Definition von Type t und Dynamic
Dynamisches Type-checking
Zusammenfassung
(1) Liste dynamischer Werte
Eine Liste von Dynamics kann nun als unendliche
Parameterliste für printf verwendet werden
Phantom Types
Fabian Franzelin
Einführung
Motivation
Haskell
Phantom Types
Beispiele
[Dyn RChar ’a’, Dyn (RList RChar) “Fabian”]
[Dyn RInt 27, Dyn (RPair RInt RChar) (1, ’a’)]
Beispiel - Die Peanozahlen
Weitere
Anwendungsmöglichkeiten
C-style printf in Haskell
Typrepräsentanten und
dynamische Werte
Dynamisches Type-checking
Zusammenfassung
Die Funktionssignatur lässt sich nun ähnlich zur
C-Funktion angeben
Haskell Funktionssignatur für printf
printf :: String → [Dynamic ] → Maybe String
(2) Dynamisches Type-checking
Ein bestimmter Tag erwartet einen Wert eines bestimmten
Typs
Es muss zur Laufzeit sichergestellt werden, dass auch der
geforderte Typ vorliegt ⇒ Type-checking
Die tequal Funktion
Phantom Types
Fabian Franzelin
Einführung
Motivation
Haskell
Phantom Types
Beispiel - Die Peanozahlen
Weitere
Anwendungsmöglichkeiten
C-style printf in Haskell
Typrepräsentanten und
dynamische Werte
tequal :: Type t → Type v → Maybe (t → v )
Dynamisches Type-checking
Zusammenfassung
Beispiele
tequal RInt RInt ⇒ Just id
tequal (RList RChar) (RList RInt) ⇒ Nothing
(2) Casting
Im zweiten Schritt muss bei erfolgreichem Type-checking
der dynamischen Wert in den erwarteten Typ gecastet
werden
Phantom Types
Fabian Franzelin
Einführung
Motivation
Haskell
Phantom Types
Beispiel - Die Peanozahlen
Die cast Funktion
Weitere
Anwendungsmöglichkeiten
C-style printf in Haskell
cast :: ∀t .Dynamic → Type t → Maybe t
Typrepräsentanten und
dynamische Werte
Dynamisches Type-checking
cast (Dyn ra a) rb = fmap (\f -> f a) (tequal ra rb)
Beispiele
cast (Dyn RInt 27) RInt ⇒ Just 27
cast (Dyn (RList RChar) “Fabian”) (RList
RInt) ⇒ Nothing
Zusammenfassung
C-Style printf in Haskell
Letzter Schritt: String parsen und Tags erkennen
Phantom Types
Fabian Franzelin
Einführung
Motivation
Haskell
Beispiele
Phantom Types
Beispiel - Die Peanozahlen
printf “Hallo, mein Name ist %s” [Dyn
(RList Char) “Fabian”]
⇒ “Hallo, mein Name ist Fabian”
Weitere
Anwendungsmöglichkeiten
printf “Ich bin %d Jahre alt” [Dyn
RInt 27]
⇒ “Nothing”
Zusammenfassung
C-style printf in Haskell
Typrepräsentanten und
dynamische Werte
Dynamisches Type-checking
Outline
Phantom Types
Fabian Franzelin
Einführung
Einführung
Motivation
Haskell
Motivation
Haskell
Phantom Types
Beispiel - Die Peanozahlen
Weitere
Anwendungsmöglichkeiten
Phantom Types
Beispiel - Die Peanozahlen
C-style printf in Haskell
Typrepräsentanten und
dynamische Werte
Dynamisches Type-checking
Zusammenfassung
Weitere Anwendungsmöglichkeiten
C-style printf in Haskell
Typrepräsentanten und dynamische Werte
Dynamisches Type-checking
Zusammenfassung
Zusammenfassung
Unterschied zwischen dynamischer und statischer
Typisierung
Dynamische Typisierung in statisch typisiertem System
integriert unter der Verwendung von Phantom Types ohne
eine Beeinträchtigung der Korrektheitseigenschaft möglich
Vorgestellte Anwendungsbeispiele:
Einfache Ausdruckssprache mit Evaluierungsfunktion
eval
Typrepräsentanten und dynamischen Werten mit
beispielhafter printf Implementierung
Weiteres Anwendungsbeispiel:
Universelle Traversierungsfunktion über Phantom Types
Phantom Types
Fabian Franzelin
Einführung
Motivation
Haskell
Phantom Types
Beispiel - Die Peanozahlen
Weitere
Anwendungsmöglichkeiten
C-style printf in Haskell
Typrepräsentanten und
dynamische Werte
Dynamisches Type-checking
Zusammenfassung
Literaturverzeichnis
James Cheney and Ralf Hinze.
A lightweight implementation of generics and dynamics.
In Proceedings of the 2002 ACM SIGPLAN Haskell Workshop, pages 90–104. ACM-Press, Oktober 2002.
Phantom Types
Fabian Franzelin
Einführung
Motivation
Haskell
James Cheney and Ralf Hinze.
Phantom types.
Technical report, Cornell University, May 2003.
Phantom Types
Ralf Hinze.
Fun with phantom types.
http://www.comlab.ox.ac.uk/people/ralf.hinze/talks/FOP.pdf, März 2003.
Weitere
Anwendungsmöglichkeiten
Beispiel - Die Peanozahlen
C-style printf in Haskell
Richard B. Kieburtz.
Automated soundness checking of a programming logic for haskell.
programatica.cs.pdx.edu/P/kieburtz.pdf, 2002.
Jörg Kreiker.
Vorlesung: Programming languages.
Technische Unversität München, 2010/2011.
Daan Leijen and Erik Meijer.
Domain-specific embedded compilers.
In Proceedings of the 2nd Conference on Domain-Specific-Languages, pages 109–122, Oktober 1999.
Mark Shields and Simon Peyton Jones.
Object-oriented style overloading for haskell, 2001.
Typrepräsentanten und
dynamische Werte
Dynamisches Type-checking
Zusammenfassung
Herunterladen