Liniowość nie jest wystarczającym ograniczeniem, aby określić unikalną reprezentację stanową, więc odpowiedź na twoje pytanie zależy od tego, jak interpretujesz logikę liniową w kategoriach stanu. Zazwyczaj znajdzie to odzwierciedlenie w sposobie interpretowania Modalność.!A
Jeśli planowana semantyka odniesień mówi, że wszystkie wskaźniki są unikatowymi wartościami (tzn. Istnieje co najwyżej jedno odniesienie do obiektu), wówczas dags i struktury grafów nie są wyrażalne, z tego rodzaju tautologicznego powodu, że dag może zawierać wiele odniesień do ten sam obiekt. W tym przypadku Musi być obliczenia , które tworzy nową wartość typu A , ponieważ chcesz Maps!AAI.δA:!A⊸!A⊗!AϵA:!A⊸A
Załóżmy jednak, że chcesz reprezentować udostępnianie . Następnie obiekty można zbierać w pomocą liczenia referencji za pomocą map i można realizować jako operacje, które po prostu podważają referencje. W takim przypadku nie można użyć liniowości, aby założyć, że mutacja wartości zawsze jest bezpieczna, ponieważ istnieje współdzielenie. Możesz jednak upewnić się, że cała alokacja pamięci jest jawna w twoim programie i że nie ma żadnych cykli na stercie.!AδA:!A⊸!A⊗!AϵA:!A⊸A
W najbardziej praktycznych implementacjach typów liniowych nie stosuje się żadnej z tych dwóch interpretacji. Zamiast tego referencje są postrzegane jako dowolnie powielane jednostki, a to, co śledzimy liniowo, to w rzeczywistości możliwości . Możliwości nie są wartościami środowiska wykonawczego; są to podmioty czysto koncepcyjne, które mają reprezentować pozwolenie na dostęp do odniesienia. Chodzi o to, że programujesz w stylu przekazywania uprawnień, a więc nawet jeśli istnieje wiele odniesień do tego samego obiektu, odczyt lub modyfikacja elementu stanu może nastąpić tylko wtedy, gdy masz również dostęp do niego. A ponieważ zdolność jest liniowa, wiesz, że tylko Ty możesz to zmienić.
n e wg e ts e tc o p y::::∀ α .a- ⊸ ∃ 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 )
W zarysowanym powyżej interfejsie API, zakresy powyżej ι , niektóre dziedziny wskaźników czasu kompilacji i zakresy α ponad typami. Mamy typ c a p ( c ), który jest zdolnością indeksowaną przez c , oraz typ r e f ( α , c ) , który jest rodzajem odniesień do α, do którego dostęp uzyskuje zdolność c . Wywołanie g e t i s e t na referencji wymaga zdolności c , a wywołanie n edoιαc a p (c)dor e f( α , c )αdog e ts e tdo tworzy nowe odniesienie i nową możliwość współużytkowania wspólnego indeksu. Jednakże, c o P r -nia odniesienie nie wymaga dostępu do jakiegokolwiek możliwości, to każdy może kopiować odniesienia, jak długo nie wyglądają w środku.n e wc o p y