Singleton types et parametricity
Singleton types
•
Les types d ´ependants des pauvres Parametricity•
Th ´eor `emes gratuits!Singleton types partout
∼
parametricity partoutProbl `emes avec les types d ´ependants
Incompatibles avec:
•
Mutation: incoh ´erence•
Exceptions•
R ´ecursion: v ´erification de types ind ´ecidable•
Compilation: chaque phase de compilation est un probl `eme ouvert•
...Attrayant pour un assistant `a la preuve, mais:
GADTs: types “d ´ependants” sans arri `ere go ˆ ut
On remplace:
type Nat : Type | zero : Nat | succ : Nat -> Nat;
type NList (a : Type) (l : Nat)
| nnil : NList a zero
| ncons: a -> NList a l -> NList a (succ 1);
par
Zero : Type;
Succ : Type -> Type;
type NList a l
| nnil : NList a Zero
| ncons: a -> NList a l -> NList a (Succ 1);
GADTs
Pr ´eserve la “phase distinction”
Compatible avec les effets de bord, la compilation, ...
Disponible en Haskell, OCaml, Scala, ...
N ´ecessite une inf ´erence/v ´erification de types plus sophistiqu ´ee Se r ´eduit fondamentalement aux preuves d’ ´egalit ´e d’
Ω
megaLa saveur des types d ´ependants, mais sans la d ´ependance
Typage des GADTs
Le probl `eme du typage des GADTs:
Le raffinement des types dans les branches
case (ys : NList a l)
| nnil => nnil
| ncons x xs => ncons x xs
Il faut se souvenir que
l =
Zero dans la premi `ere brancheTenir compte des ces ´egalit ´es lors de v ´erification d’ ´egalit ´e d’autres types Plusieurs typages possibles
⇒
annotations pour aider l’inf ´erenceLe type de make-nlist?
Avec typage d ´ependent:
make-nlist : a -> (len : Nat) -> NList a len;
Avec GADTs:
make-nlist : a -> (len : ?Nat?) -> NList a ?len?;
Nat n’existe plus (ou du moins, pas comme type) len n’existe pas dans le monde des types
Les types singleton `a la rescousse
type singleton: un type qui n’a qu’une seule valeur possible
Par exemple Snat
n
, le type des nombres qui valentn
:make-nlist : ∀ len. a -> Snat len -> NList a len;
On a maintenant acc `es `a len dans les 2 mondes: types et valeurs Mais, toujours pas de types d ´ependents!
Mais il faut dupliquer certaines choses:
(+) : ∀ n1, n2. Snat n1 -> Snat n2
-> Snat (plus n1 n2);
Types singleton partout
Les types singleton sont ´equivalents aux types d ´ependants
Param ´etricit ´e
∀t.t → t
est un singleton typeDe m ˆeme, il n’y a pas de valeur de type
∀t.
Nat→ t
Ceci peut se d ´eduire donc directement du type
La param ´etricit ´e est une propri ´et ´e g ´en ´erale `a partir de laquelle on peut prouver ces autres propri ´et ´es
Exemples
head
: ∀t.[t] → t f ◦
head'
head◦
mapf
(++)
: ∀t.[t] → [t] → [t]
mapf (x
++y) '
mapf x
++ mapf y K : ∀t
1, t
2.t
1→ t
2→ t
1f (K x y) ' K (f x) (g y )
zip
: ∀t
1, t
2.([t
1], [t
2])
→ [(t
1, t
2)]
zip
(
mapf x,
mapg y)
'
map(f × g)
zip(x, y)
Mod `eles
Un mod `ele d’un langage est un mapping vers un formalisme standard Exemple:
Γ ` e : τ ⇒ J e K
Γ∈ J τ K
ΓJ n K
Γ⇒ n
J Int K
Γ⇒ Z
Mod `ele pour System F
Pour la param ´etricit ´e, on d ´efini une sorte de mod `ele Les types sont traduits en relations binaires
e : τ ⇒ e J τ K e
Pour un type de base
τ
, la relation est la relation identit ´eJ
BoolK :
Bool⇔
Bool= I
BoolSi
J τ K = R : A ⇔ A
0alors
J [τ ] K = R
0: [A] ⇔ [A
0]
Mod `ele de fonctions
Si
J τ
1K : A ⇔ A
0et
J τ
2K : B ⇔ B
0alors
J τ
1→ τ
2K : A → B ⇔ A
0→ B
0tel que
f J τ
1→ τ
2K f
0 iff∀x, x
0. x J τ
1K x
0⇒ f x J τ
2K f
0x
0Functions are related if they take
related input arguments to related output results
Mod `ele de polymorphisme
J ∀t.F t K : (∀t.F t) ⇔ (∀t
0.F
0t
0)
soit
F
une fonction de relation `a relation telle que pour toute relationR : A ⇔ A
0 il y a une relationF R : F A ⇔ F
0A
0.alors
f J ∀t.F t K f
0 iff∀A, A
0, R : A ⇔ A
0. f [A] (F R) f
0[A
0]
Polymorphic functions are related if they take related input types to related output values
Th ´eor `eme de param ´etricit ´e
Le th ´eor `eme de param ´etricit ´e, dit simplement:
Si
• ` e : τ
alorse J τ K e
Cela revient `a dire que le mod `ele est valide
Usage
Prenons notre premier exemple
f : ∀t. t → t
Le th ´eor `eme nous dit
∀x
1, x
2, R. x
1R x
2⇒ (f x
1) R (f x
2);
On peut alors l’instancier avec:
x
1= x, x
2= x, R = {(x, x)}
Ce qui nous donne:
(f x) R (f x) ⇒ (f x, f x) ∈ {(x, x)} ⇒ f x = x
Avec Curry-Howard
alors
J τ
1→ τ
2K : A → B ⇔ A
0→ B
0tel que
f J τ
1→ τ
2K f
0 iff∀x, x
0. x J τ
1K x
0⇒ f x J τ
2K f
0x
0Devient:
f J τ
1→ τ
2K f
0= (x : A) → (x
0: A
0) → (P : x J τ
1K x
0)
→ (f x J τ
2K f
0x
0)
A.K.A