Ответ 1
Вероятно, лучше всего посмотреть, что SafeHaskell позволяет:
Безопасный язык
Безопасный язык (включен через
-XSafe
) ограничивает вещи двумя способами:
- Некоторые расширения GHC LANGUAGE полностью запрещены.
- Некоторые расширения GHC LANGUAGE ограничены в функциональности.
Ниже точно указаны флаги и расширения в каждой категории:
- Запрещено полностью:
GeneralizedNewtypeDeriving
,TemplateHaskell
- Ограниченная функциональность:
OverlappingInstances
,ForeignFunctionInterface
,RULES
,Data.Typeable
- См. раздел Ограниченные функции ниже
- Не имеет значения: все остальные флаги.
Ограниченные и отключенные функции GHC Haskell
На диалекте "Безопасный язык" мы ограничиваем следующие возможности языка Haskell:
ForeignFunctionInterface
: это в основном безопасно, но запрещены импортные импортные объявления, которые импортируют функцию с типом, отличным от IO. Весь импорт FFI должен находиться в IO Monad.RULES
: поскольку они могут непредсказуемо изменять поведение доверенного кода, нарушая семантическую согласованность, они ограничены в функции. В частности, всеRULES
, определенные в модулеM
, скомпилированном с-XSafe
, отбрасываются.RULES
, определенный в надежных модулях, что импортM
по-прежнему действителен и будет срабатывать, как обычно.OverlappingInstances
: это расширение может использоваться для нарушения семантической согласованности, поскольку вредоносный код может переопределять экземпляр типа (путем определения более конкретного экземпляра) таким образом, который изменяет поведение кода, импортирующего ненадежный модуль. Расширение не отключено для модуляM
, скомпилированного с помощью-XSafe
, но ограниченного. ПокаM
может определять перекрывающиеся объявления экземпляров, их можно использовать только вM
. Если в модулеN
, который импортируетM
, на сайте вызова, который использует функцию класса типа, существует выбор того, какой экземпляр использовать (т.е. перекрытие), а наиболее конкретный выбор - отM
(или любого другой безопасный скомпилированный модуль), то компиляция завершится неудачно. Не имеет значения, если модульN
считается безопасным, или заслуживающим доверия, или ни тем, ни другим.Data.Typeable
: Мы разрешаем выводData.Typeable
, но мы не разрешаем экземпляры вручную. Производные экземпляры являются машинами, сгенерированными GHC, и должны быть абсолютно безопасными, но обработанные вручную могут лежать о своем типе и допускать небезопасные принуждения между типами. Это находится в духе оригинального дизайна SYB.В диалоговом языке "Безопасный язык" мы полностью отключим следующие возможности языка Haskell:
GeneralizedNewtypeDeriving
: он может использоваться для нарушения контроля доступа к конструктору, позволяя ненадежному коду манипулировать защищенными типами данных способами, которые не создавал автор типа данных. I. можно использовать для разрыва инвариантов структур данных.TemplateHaskell
: Это особенно опасно, так как это может вызвать побочные эффекты даже во время компиляции и может использоваться для доступа к абстрактным типам данных. Очень легко сломать границы модулей с помощью TH.
Я помню, что прочитал, что взаимодействие FunctionalDependencies
и UndecidableInstances
также может быть небезопасным, поскольку за пределами возможности неограниченной глубины стека контекста UndecidableInstances
также поднимается так называемый условие покрытия (раздел 7.6.3.2), но я не могу найти ссылку для этого на данный момент.
EDIT 2015-10-27: С тех пор, как GHC получил поддержку ролей типов, GeneralizedNewtypeDeriving
уже не является безопасным. (Я не уверен, что еще могло измениться.)