来自GHC手册,安全语言部分
模块边界控制-使用安全语言编译的Haskell代码保证只访问通过其他模块导出列表向它公开提供的符号。其中一个重要部分是,安全编译的代码无法使用它无法导入的数据构造函数来检查或创建数据值。如果模块M通过仔细使用导出列表来建立不变量,那么使用导入M的安全语言编译的代码就可以保证尊重这些不变量。因此,模板Haskell和
GeneralizedNewtypeDeriving
在安全语言中被禁用,因为它们可以用于违反此属性.。
如何使用GeneralizedNewtypeDeriving
破坏模块的不变量
发布于 2013-06-16 13:03:24
卢基链接到我的博客文章关于这一主题。基本上,在GHC中实现的GeneralizedNewtypeDeriving
假设某种同构(即newtype
所隐含的操作无关同构)意味着leibniz相等。这在Haskell 98中是正确的,但在Haskell加上扩展中完全不正确。
也就是说,新类型提供了一对函数。
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.
--我对此有更好的理解,并且更有信心的是,如果没有"System“风格的扩展(类型系列,GADT),GeneralizedNewtypeDeriving
无法生成unsafeCoerce
。窗台,它是不安全的,应该小心使用,如果有的话。我的理解是,Lennart Augustsson (用户augustss)在hbc中实现它的方式非常不同,而且这种实现是安全的。一个安全的实现将是更有限的,更复杂的。
更新:有了新版本的GHC (所有问题都应该从7.8.1开始消失),GeneralizedNewtypeDeriving
是安全的,因为有了新的角色系统
https://stackoverflow.com/questions/17137111
复制相似问题