Safe Haskell по сути является подмножеством языка Haskell. Он направлен на отключение некоторых часто используемых "трюков", например, unsafePerformIO :: IO a -> a
, и, кроме того, он (стремится) гарантировать, что вы каким-то образом не получите доступ к частным функциям , конструкторы данных и др. c. модуля, цель которого - предотвратить доступ к ним. Вкратце сейф Haskell гарантирует три вещи:
- Ссылочная прозрачность ;
- Контроль границ модуля ; и
- Semanti c согласованность .
Безопасный модуль должен соответствовать этим ограничениям и, кроме того, работать только с безопасными модулями. Безопасный модуль, конечно, не означает, что код, с которым он работает, правильный, или что действие IO
, например, не может быть вредоносным. Но у него есть некоторые гарантии, поскольку, если функция имеет тип, который не имеет IO
, то обычно модуль не должен иметь возможность выполнять IO
небезопасным способом.
Определенные расширения, такие как TemplateHaskell
и указание прагмы {-# RULES … #-}
не допускается в сейфе Haskell. Другие расширения, такие как DeriveDataTypeable
, разрешены, но только в том случае, если вы используете предложение deriving
для создания экземпляра и, следовательно, не генерируете собственный.
Однако для некоторых модулей требуется , чтобы использовать расширения для правильной работы. В этом случае автор может пометить модуль как Trustworthy
. Это означает, что автор утверждает, что модуль предоставляет безопасный API, но что он внутренне должен работать с некоторыми небезопасными расширениями, прагмами и т. Д. c. Таким образом, компилятор не может гарантировать безопасность.
Эти расширения описаны в документации :
Расширение Safe Haskell включает следующие три языковых флага:
XSafe
- включает безопасный диалект языка , запрашивая GH C, чтобы гарантировать доверие. Диалект безопасного языка требует, чтобы весь импорт был доверенным, иначе возникнет ошибка компиляции. XTrustworthy
- означает, что хотя этот модуль может вызывать небезопасные функции внутри, автор модуля утверждает, что он экспортирует API который нельзя использовать небезопасным способом . Это не включает безопасный язык и не накладывает никаких ограничений на разрешенный код Haskell. Гарантия доверия предоставляется автором модуля, а не GH C. Оператор импорта с ключевым словом safe приводит к ошибке компиляции, если импортированный модуль не является доверенным. Оператор импорта без ключевого слова ведет себя как обычно и может импортировать любой модуль, независимо от того, является ли он доверенным или нет. XUnsafe
- помечает компилируемый модуль как небезопасный, чтобы модули, скомпилированные с использованием -XSafe, не могли его импортировать.