Почему GeneralizedNewtypeDeriving не является безопасным Haskell?

из руководства GHC, раздел Безопасный Язык:

модуль пограничного контроля - код Haskell, скомпилированный с использованием безопасного языка, гарантирует доступ только к символам, которые общедоступны для него через другие списки экспорта модулей. Важной частью этого является то, что безопасный скомпилированный код не может проверять или создавать значения данных с помощью конструкторов данных, которые он не может импортировать. Если модуль M устанавливает некоторые инварианты через careful использование его списка экспорта, а затем код, скомпилированный с использованием безопасного языка, который импортирует M, гарантирует уважение этих инвариантов. Из-за этого шаблон Haskell и GeneralizedNewtypeDeriving отключены на безопасном языке, поскольку они могут быть использованы для нарушения этого свойства.

Как можно разбить инварианты модуля, используя GeneralizedNewtypeDeriving?

1 ответов


Luqui связан с мой блог на эту тему. В основном, GeneralizedNewtypeDeriving как реализовано в GHC предполагает, что определенный вид изоморфизма (а именно операционально нерелевантный изоморфизм, подразумеваемый newtype) подразумевает равенство Лейбница. Это было верно в Haskell 98 вроде ... но это не все true в расширениях Haskell plus.

то есть, newtype предоставляет пару функций

a -> b
b -> a

это ничего не делает в ядре, но это не нормально, чтобы заключить

forall f. f a -> f b

, потому что f может быть функцией типа или GADT. Это форма равенства, необходимая для GeneralizedNewtypeDeriving

даже в Haskell 98 он ломает границы модуля. Вы можете иметь такие вещи, как

class FromIntMap a where
  fromIntMap :: Map Int b -> Map a b

instance FromIntMap Int where
  fromIntMap = id

newtype WrapInt = WrapInt Int deriving FromIntMap

instance Ord WrapInt where
  WrapInt a <= WrapInt b = b <= a

что будет делать плохие вещи...

в моем блоге показано, как реализовать unsafeCoerce несколько способов использования других расширений (все безопасно) и GeneralizedNewtypeDeriving. у меня есть лучшее понимание того, почему это сейчас, и я гораздо увереннее, что GeneralizedNewtypeDeriving не может произвести unsafeCoerce без расширений стиля "System FC" (тип familes, GADTs). Подоконник, он небезопасен и должен использоваться с осторожностью, если вообще. Я понимаю, что Леннарт Августссон (пользователь augustss) реализовал его совсем по-другому в hbc, и эта реализация была безопасной. Безопасное осуществление было бы более ограниченным и более сложным.

UPDATE: с новыми версиями GHC (все проблемы должны исчезнуть с 7.8.1) GeneralizedNewtypeDeriving безопасно из-за нового система ролей