Haskell - безопасные и заслуживающие доверия расширения - PullRequest
4 голосов
/ 07 мая 2020

Глядя на какой-то код в hackage, я наткнулся на расширения Safe и Trustworthy.

Что они означают в целом (или точно ...)? Есть ли хорошее практическое правило, когда их использовать, а когда нет?

1 Ответ

7 голосов
/ 07 мая 2020

Safe Haskell по сути является подмножеством языка Haskell. Он направлен на отключение некоторых часто используемых "трюков", например, unsafePerformIO :: IO a -> a, и, кроме того, он (стремится) гарантировать, что вы каким-то образом не получите доступ к частным функциям , конструкторы данных и др. c. модуля, цель которого - предотвратить доступ к ним. Вкратце сейф Haskell гарантирует три вещи:

  1. Ссылочная прозрачность ;
  2. Контроль границ модуля ; и
  3. 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, не могли его импортировать.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...