La linéarité n'est pas une contrainte suffisante pour définir une représentation avec état unique, et donc la réponse à votre question dépend de la façon dont vous interprétez la logique linéaire en termes d'état. Cela se reflétera généralement dans la façon dont vous devez interpréter le ! UNE modalité.
Si la sémantique voulue des références indique que tous les pointeurs sont des valeurs uniques (c'est-à-dire qu'il n'y a au plus qu'une seule référence à un objet), les dags et les structures de graphe ne sont pas exprimables, pour le type de raison tautologique qu'un dag peut contenir plusieurs références à le même objet. Dans ce cas doit être un calcul qui crée une nouvelle valeur de type A , puisque vous voulez des cartes Et .! UNEUNEε A : ! A ⊸ AδUNE: ! Un ⊸ ! Un ⊗ ! UNEϵUNE: ! A ⊸ A
Cependant, supposons que vous voulez pour représenter le partage . Ensuite, les objets peuvent être récupérés avec le comptage des références, avec les cartes et peuvent être réalisées comme des opérations qui ne font que bousculer les comptages de références. Dans ce cas, vous ne pouvez pas utiliser la linéarité pour supposer qu'il est toujours sûr de muter les valeurs, car il y a partage. Mais vous pouvez vous assurer que toute l'allocation de mémoire est explicite dans votre programme et qu'il n'y a pas de cycles dans le tas.δ A : ! Un ⊸ ! Un ⊗ ! A ε A : ! A ⊸ A! UNEδUNE: ! Un ⊸ ! Un ⊗ ! UNEϵUNE: ! A ⊸ A
La plupart des implémentations pratiques de types linéaires n'utilisent aucune de ces deux interprétations. Au lieu de cela, les références sont considérées comme des entités librement reproductibles, et ce que nous suivons de manière linéaire sont en fait des capacités . Les capacités ne sont pas des valeurs d'exécution; ce sont des entités purement conceptuelles qui sont censées représenter l'autorisation d'accéder à une référence. L'idée est que vous programmez dans un style de passage d'autorisations, et donc même s'il existe de nombreuses références au même objet, une lecture ou une modification d'un élément d'état ne peut se produire que si vous avez également la possibilité d'y accéder. Et puisque la capacité est linéaire, vous savez que vous seul pouvez la changer.
n e wg e ts e tc o p y::::∀ α .α ⊸ ∃ c : ι . c a p ( c ) ⊗ r e f( α , c )∀ α , c : ι .c a p (c)⊗ r e f( α , c ) ⊸ α ⊗ c a p ( c ) ⊗ r e f( α , c )∀ α , c : ι .c a p (c)⊗ r e f( α , c ) ⊗ α ⊸ c a p ( c ) ⊗ r e f( α , c )∀ α , c : ι .r e f( α , c ) ⊸ r e f( α , c ) ⊗ r e f( α , c )
Dans l'API esquissée ci-dessus, s'étend sur , certains domaines d'indices au moment de la compilation et étend sur les types. Nous avons un type qui est une capacité indexée par , et un type , qui est un type de références à accessible par une capacité . L'appel de et sur une référence nécessite la capacité , et l'appel de crée une nouvelle référence et une nouvelle capacité partageant un index commun. Cependant,ι α c a p ( c ) c r e f ( α , c ) α c g e t s e t c n e w c o p ycιαc a p (c)cr e f( α , c )αcg e ts e tcn e wc o p y-une référence ne nécessite aucun accès à aucune capacité, donc n'importe qui peut copier une référence tant qu'il n'y regarde pas.