Luqui 链接到我关于该主题的博客文章。基本上,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.
对现在的原因有了更好的理解,并且更有信心如果没有“System FC”风格的扩展(类型家族, GADT)。Sill,它是不安全的,如果有的话,应该小心使用。我的理解是 Lennart Augustsson(用户 augustss)在 hbc 中实现它的方式非常不同,而且这种实现是安全的。一个安全的实现会更受限制,也更复杂。GeneralizedNewtypeDeriving
unsafeCoerce
更新:使用足够新的 GHC 版本(从 7.8.1 开始,所有问题都应该消失)GeneralizedNewtypeDeriving
是安全的,因为新的角色系统