Есть ли список расширений GHC, которые считаются «безопасными»?

Иногда часть кода, которую я хочу написать, не является законной без хотя бы одного расширения языка. Это особенно актуально, когда вы пытаетесь внедрить идеи в исследовательские документы, которые, как правило, используют ту, какая быстрая, сверхдлинная версия GHC была доступна в то время, когда была написана статья, не давая понять, какие расширения действительно требуются.

В результате я часто получаю что-то вроде этого в верхней части моих файлов .hs:

{-# LANGUAGE TypeFamilies , MultiParamTypeClasses , FunctionalDependencies , FlexibleContexts , FlexibleInstances , UndecidableInstances , OverlappingInstances #-} 

Я не против этого, но часто чувствую, что я делаю слепые жертвы, чтобы успокоить Великого Бога GHC. Он жалуется, что определенный fragment кода недействителен без расширения языка X, поэтому я добавляю прагму для X. Затем он требует включения Y, поэтому я добавляю прагму для Y. К тому времени, когда это закончится, я включите три или четыре расширения языка, которые я действительно не понимаю, и я понятия не имею, какие из них «безопасны».

Объяснить, что я подразумеваю под «безопасным»:

  • Я понимаю, что UndecidableInstances безопасен, потому что, хотя это может привести к тому, что компилятор не завершится, пока компиляция кода не будет иметь неожиданных побочных эффектов.

  • С другой стороны, OverlappingInstances явно небезопасно, потому что мне очень легко случайно записать код, который дает ошибки времени выполнения.

Поэтому мой вопрос:

Есть ли список GHCextensions, которые считаются «безопасными» и которые являются «небезопасными»?

Вероятно, лучше всего посмотреть, что позволяет SafeHaskell :

Безопасный язык

Безопасный язык (включен через -XSafe ) ограничивает вещи двумя способами:

  1. Некоторые расширения GHC LANGUAGE полностью запрещены.
  2. Некоторые расширения 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 данных Data.Typeable , но мы не разрешаем экземпляры вручную. Производные экземпляры являются машинами, сгенерированными GHC, и должны быть абсолютно безопасными, но обработанные вручную могут лежать о своем типе и допускать небезопасные принуждения между типами. Это находится в духе оригинального дизайна SYB.

На диалоговом языке «Безопасный язык» мы полностью отключили следующие возможности языка Haskell:

  • GeneralizedNewtypeDeriving : его можно использовать для нарушения контроля доступа к конструктору, позволяя ненадежному коду манипулировать защищенными типами данных способами, которые не создавал автор типа данных. Т.е. можно использовать для разрыва инвариантов структур данных.
  • TemplateHaskell : Особенно опасен, поскольку он может вызывать побочные эффекты даже во время компиляции и может использоваться для доступа к абстрактным типам данных. Очень легко сломать границы модhive с помощью TH.

Я помню, что прочитал, что взаимодействие FunctionalDependencies и UndecidableInstances также может быть небезопасным, потому что, помимо возможности неограниченной глубины стека контекста UndecidableInstances также снимает так называемое условие покрытия (раздел 7.6.3.2), но я не могу найти ссылку для этого в данный момент.

EDIT 2015-10-27: С тех пор, как GHC получил поддержку ролей типа, GeneralizedNewtypeDeriving больше не является небезопасным. (Я не уверен, что еще могло измениться.)

  • Существует ли игла Haskell для обновления вложенной структуры данных?
  • Что представляет собой складку для других типов, кроме списка?
  • : спринт для полиморфных значений?
  • Как функторы работают в haskell?
  • Является ли оператор monad bind (>> =) ближе к функциональному составу (цепочке) или приложению функции?
  • Haskell: как оценить строку типа «1 + 2»
  • Что такое Haskell's Stream Fusion
  • Как вы представляете график в Haskell?
  • Что плохого в ленивом вводе-выводе?
  • Как мне написать: «если typeclass a, то a также является экземпляром b по этому определению».
  • foldl против foldr с бесконечными списками
  • Давайте будем гением компьютера.