Je travaille sur un compilateur pour un langage concaténatif et je voudrais ajouter un support d'inférence de type. Je comprends Hindley – Milner, mais j'ai appris la théorie des types au fur et à mesure, donc je ne sais pas comment l'adapter. Le système suivant est-il solide et inférable?
Un terme est un littéral, une composition de termes, une citation d'un terme ou une primitive.
Tous les termes désignent des fonctions. Pour deux fonctions et , , c'est-à-dire que la juxtaposition désigne la composition inverse. Les littéraux désignent les fonctions niladiques.e 2 e 1
Les termes autres que composition ont des règles de type de base:
Les règles d'application sont particulièrement absentes, car les langues concaténatives en sont dépourvues.
Un type est soit un littéral, une variable de type, soit une fonction de piles en piles, où une pile est définie comme un tuple imbriqué à droite. Toutes les fonctions sont implicitement polymorphes par rapport au «reste de la pile».
C'est la première chose qui semble suspecte, mais je ne sais pas exactement ce qui ne va pas.
Pour faciliter la lisibilité et réduire les parenthèses, je suppose que dans les schémas de types. Je vais également utiliser une lettre majuscule pour une variable désignant une pile, plutôt qu'une seule valeur.
Il existe six primitives. Les cinq premiers sont assez inoffensifs. dup
prend la valeur la plus élevée et en produit deux copies. swap
change l'ordre des deux premières valeurs. pop
ignore la valeur supérieure. quote
prend une valeur et produit une citation (fonction) qui la renvoie. apply
applique un devis à la pile.
Le dernier combinateur compose
,, doit prendre deux citations et retourner le type de leur concaténation, c'est-à-dire . Dans le langage concaténatif de type statique Cat , le type de est très simple.compose
Cependant, ce type est trop restrictif: il nécessite que la production de la première fonction corresponde exactement à la consommation de la seconde. En réalité, vous devez assumer des types distincts, puis les unifier. Mais comment écririez-vous ce type?
Si vous laissez dénoter une différence de deux types, alors je pense que vous pouvez écrire le type de correctement.compose
Ceci est encore relativement simple: compose
prend une fonction et une . Son résultat consomme au sommet de la consommation de non produite par , et produit au sommet de la production de non consommée par . Cela donne la règle de la composition ordinaire.f 2 : D → E B f 2 f 1 D f 1 f 2
Cependant, je ne sais pas si cet hypothétique correspond en fait à quelque chose, et je le poursuis en rond depuis assez longtemps pour que je pense avoir pris un mauvais virage. Serait-ce une simple différence de tuples?
Y a-t-il quelque chose d'horriblement cassé que je ne vois pas, ou suis-je sur quelque chose comme la bonne voie? (J'ai probablement quantifié à tort certaines de ces choses et j'apprécierais également les correctifs dans ce domaine.)
compose
est trop restrictive? J'ai l'impression que c'est bien comme ça. (par exemple la restriction pourrait être gérée par unification comme pour une application similaire dans le λ-calcul)
twice
défini comme dup compose apply
, qui prend une citation et l'applique deux fois. [1 +] twice
c'est bien: vous composez deux fonctions de type . Mais ce n'est pas le cas: si , le problème est que , donc l'expression est interdite même si elle doit être valide et avoir taper . La solution est bien sûr de mettre le qualificatif au bon endroit, mais je me demande principalement comment écrire réellement le type de sans définition circulaire. ∀ A b .[pop] twice
A ≠ A∀ A b .compose