Почему 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
безопасно из-за нового система ролей