D'abord une explication terminologique: les positions négatives et positives viennent de la logique. Ils sont sur une asymétrie dans connecteurs logiques: en l' A se comporte différemment de B . Une chose similaire se produit dans la théorie des catégories, où nous disons contravariant et covariant au lieu de négatif et positif, respectivement. En physique, ils parlent de quantités qui se comportent "de manière covariante" et "contravariante aussi. C'est donc un phénomène très général. Un programmeur pourrait les considérer comme" entrée "et" sortie ".A ⇒ BUNEB
Passons maintenant aux types de données inductifs.
Considérez un type de données inductive comme une sorte de structure algébrique: constructeurs sont les opérations qui ont des éléments de T comme arguments et produire de nouveaux éléments de T . C'est très similaire à l'algèbre ordinaire: l'addition prend deux nombres et produit un nombre.TTT
En algèbre, il est habituel qu'une opération prenne un nombre fini d'arguments, et dans la plupart des cas, elle prend zéro (constant), un (unaire) ou deux (binaire) arguments. Il est commode de généraliser cela pour les constructeurs de types de données. Supposons que c
c'est un constructeur pour un type de données T
:
- si
c
est une constante, nous pouvons la considérer comme une fonction unit -> T
, ou de manière équivalente (empty -> T) -> T
,
- si
c
est unaire, nous pouvons le considérer comme une fonction T -> T
, ou de manière équivalente (unit -> T) -> T
,
- si
c
est binaire, nous pouvons le considérer comme une fonction T -> T -> T
, ou de manière équivalente T * T -> T
, ou équivalente (bool -> T) -> T
,
- si nous voulions un constructeur
c
qui prend sept arguments, nous pourrions le voir comme une fonction (seven -> T) -> T
où se seven
trouve un type précédemment défini avec sept éléments.
- nous pouvons également avoir un constructeur
c
qui prend une infinité d'arguments, ce serait une fonction (nat -> T) -> T
.
Ces exemples montrent que la forme générale d'un constructeur doit être
c : (A -> T) -> T
où nous appelons A
l' arité de c
et nous pensons c
comme un constructeur qui prend A
-nombreux arguments de type T
pour produire un élément de T
.
Voici quelque chose de très important: les arités doivent être définies avant de définir T
, sinon nous ne pouvons pas dire ce que les constructeurs sont censés faire. Si quelqu'un essaie d'avoir un constructeur
broken: (T -> T) -> T
puis la question "combien d'arguments broken
faut-il?" n'a pas de bonne réponse. Vous pouvez essayer d'y répondre avec "il faut T
-de nombreux arguments", mais cela ne fonctionnera pas, car il T
n'est pas encore défini. Nous pourrions essayer de sortir du cunundrum en utilisant une théorie de point fixe sophistiquée pour trouver un type T
et une fonction injective (T -> T) -> T
, et réussirions, mais nous briserions également le principe d'induction pour le T
long du chemin. Donc, c'est juste une mauvaise idée d'essayer une telle chose.
λvλ ⋅ vc
B
c : B * (A -> T) -> T
En effet, de nombreux constructeurs peuvent être réécrits de cette façon, mais pas tous, nous avons besoin d'une étape de plus, à savoir que nous devrions permettre A
de dépendre de B
:
c : (∑ (x : B), A x -> T) -> T
Il s'agit de la forme finale d'un constructeur pour un type inductif. C'est aussi précisément ce que sont les types W. La forme est si générale que nous n'avons besoin que d'un seul constructeur c
! En effet, si nous en avons deux
d' : (∑ (x : B'), A' x -> T) -> T
d'' : (∑ (x : B''), A'' x -> T) -> T
alors nous pouvons les combiner en un seul
d : (∑ (x : B), A x -> T) -> T
où
B := B' + B''
A(inl x) := A' x
A(inr x) := A'' x
Soit dit en passant, si nous curry la forme générale, nous voyons qu'elle est équivalente à
c : ∏ (x : B), ((A x -> T) -> T)
ce qui est plus proche de ce que les gens écrivent réellement dans les assistants de preuve. Les assistants de preuve nous permettent d'écrire les constructeurs de manière pratique, mais ceux-ci sont équivalents à la forme générale ci-dessus (exercice!).
A
la pile et éventuellement l'exploser (dans les langages basés sur la pile).