为什么不是';不能用新类型来推导一个安全的Haskell?
来自GHC手册第节: 模块边界控制-使用安全语言编译的Haskell代码保证只访问通过其他模块导出列表公开可用的符号。其中一个重要部分是,安全编译代码无法使用无法导入的数据构造函数检查或创建数据值。如果模块M通过小心使用其导出列表建立了一些不变量,那么使用导入M的安全语言编译的代码保证尊重这些不变量。因此,模板Haskell和为什么不是';不能用新类型来推导一个安全的Haskell?,haskell,ghc,language-extension,Haskell,Ghc,Language Extension,来自GHC手册第节: 模块边界控制-使用安全语言编译的Haskell代码保证只访问通过其他模块导出列表公开可用的符号。其中一个重要部分是,安全编译代码无法使用无法导入的数据构造函数检查或创建数据值。如果模块M通过小心使用其导出列表建立了一些不变量,那么使用导入M的安全语言编译的代码保证尊重这些不变量。因此,模板Haskell和GeneralizedNewtypeDeriving在安全语言中被禁用,因为它们可用于违反此属性。 如何使用generalizednewtypedering打破模块的不变量
GeneralizedNewtypeDeriving
在安全语言中被禁用,因为它们可用于违反此属性。
如何使用generalizednewtypedering
打破模块的不变量?Luqui链接到主题上。基本上,GHC中实现的广义newtypedering假设某种同构(即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
class FromIntMap a where
fromIntMap::Map Int b->Map a b
实例FromIntMap Int,其中
fromIntMap=id
newtype WrapInt=WrapInt Int派生自intmap
实例Ord WrapInt在哪里
包装一个链接到详细说明的检查。有一个安全的,但比GHC的版本功能弱得多的版本。@augustss功能弱的版本有什么限制?功能弱的版本只是构造实例。您可以想象,当以一种非平凡的方式使用类型变量时,这是如何开始崩溃的。带有Functor
实例的容器可以工作,但仅此而已。但是,这足以派生所有常规类型类,如Eq
、Ord
、Num
,等等。在GHC 7.8或7.10中仍然不安全: