haskell - 为什么 GeneralizedNewtype 不派生一个安全的 Haskell?

标签 haskell ghc language-extension

来自 GHC 的手册,第 Safe Language 节:

Module boundary control — Haskell code compiled using the safe language is guaranteed to only access symbols that are publicly available to it through other modules export lists. An important part of this is that safe compiled code is not able to examine or create data values using data constructors that it cannot import. If a module M establishes some invariants through careful use of its export list then code compiled using the safe language that imports M is guaranteed to respect those invariants. Because of this, Template Haskell and GeneralizedNewtypeDeriving are disabled in the safe language as they can be used to violate this property.



如何使用 GeneralizedNewtypeDeriving 打破模块的不变量? ?

最佳答案

Luqui 链接到 my blog post就此主题而言。基本上,GeneralizedNewtypeDeriving正如在 GHC 中实现的那样,假设某种同构(即 newtype 隐含的操作上不相关的同构)意味着莱布尼茨相等。这在 Haskell 98 中是正确的——但在 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”样式扩展(类型家族,GADT)。 Sill,它是不安全的,如果有的话,应该小心使用。我的理解是 Lennart Augustsson(用户 augustss)在 hbc 中实现它的方式非常不同,而且这种实现是安全的。一个安全的实现会更受限制,也更复杂。

更新:使用足够新的 GHC 版本(从 7.8.1 开始,所有问题都应该消失)GeneralizedNewtypeDeriving是安全的,因为新的 roles system

关于haskell - 为什么 GeneralizedNewtype 不派生一个安全的 Haskell?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17137111/

相关文章:

haskell - Cabal:tar 存档中的文件不在预期目录中

Haskell 编译指示 : OPTIONS_GHC vs LANGUAGE

list - 为什么我得到 "Exception: Prelude.head: empty list"?

haskell - 在 Haskell 中,列表 ( '[Something] ) 前面的撇号是什么意思?

haskell - 为什么 GHC 会在这里产生等式约束错误而不是类型匹配错误?

haskell - 使用 `ghc -e` 运行 Haskell 代码时是否可以传递命令行参数?

macros - 使用 Racket 的语言扩展,通过宏定义辅助函数

haskell - 最新 GHC 中已弃用 DatatypeContexts : Why?

haskell - 与 id 组合如何更改类型

haskell - 为什么绑定(bind)到 "unrestricted"类型变量会使变量变得刚性?