Линейность не является достаточным ограничением для определения уникального представления с сохранением состояния, поэтому ответ на ваш вопрос зависит от того, как вы интерпретируете линейную логику в терминах состояния. Это обычно отражается в том, как вы должны интерпретировать модальность!A
Если ваша предполагаемая семантика ссылок говорит о том, что все указатели являются уникальными значениями (т. Е. Существует не более одной ссылки на объект), тогда дагы и графовые структуры не могут быть выражены по той тавтологической причине, что даг может содержать несколько ссылок на тот же объект. В этом случае Должен быть вычисление , которое создает новое значение типа , так как вы хотите MAPS И .A!AAδA:!A⊸!A⊗!AϵA:!A⊸A
Тем не менее, предположим, что вы хотите представлять обмен . Затем объекты можно собирать с помощью подсчета ссылок с помощью карт и могут быть реализованы как операции, которые просто увеличивают количество ссылок. В этом случае вы не можете использовать линейность, чтобы предположить, что всегда безопасно изменять значения, так как существует совместное использование. Но вы можете убедиться, что все выделение памяти в вашей программе явное и что в куче нет циклов.!AδA:!A⊸!A⊗!AϵA:!A⊸A
Большинство практических реализаций линейных типов не используют ни одну из этих двух интерпретаций. Вместо этого ссылки рассматриваются как свободно дублирующиеся объекты, а то, что мы отслеживаем линейно, фактически является возможностями . Возможности не являются значениями времени выполнения; они являются чисто концептуальными объектами, предназначенными для представления разрешения на доступ к ссылке. Идея состоит в том, что вы программируете в стиле передачи разрешений, и поэтому даже если имеется много ссылок на один и тот же объект, чтение или изменение фрагмента состояния может происходить только в том случае, если у вас также есть возможность доступа к нему. А поскольку возможности линейны, вы знаете, что только вы можете изменить их.
newgetsetcopy::::∀α.α⊸∃c:ι.cap(c)⊗ref(α,c)∀α,c:ι.cap(c)⊗ref(α,c)⊸α⊗cap(c)⊗ref(α,c)∀α,c:ι.cap(c)⊗ref(α,c)⊗α⊸cap(c)⊗ref(α,c)∀α,c:ι.ref(α,c)⊸ref(α,c)⊗ref(α,c)
В приведенном выше API-интерфейсе находится диапазоне , некоторый домен индексов времени компиляции и диапазоны в зависимости от типов. У нас есть тип который является возможностью, индексированной , и тип , который является типом ссылок на доступ к которым имеет возможность . Вызов и для ссылки требует наличия возможности , а вызов создает новую ссылку и новую возможность с общим индексом. Тем не менее,cιαcap(c)cref(α,c)αcgetsetcnewcopy- для ссылки не требуется доступ к каким-либо возможностям, поэтому любой может скопировать ссылку, если он не заглядывает внутрь нее.