简体   繁体   English

为什么不是GeneralizedNewtypeDeriving一个安全的Haskell?

[英]Why isn't GeneralizedNewtypeDeriving a Safe Haskell?

From GHC's manual, Section Safe Language : 从GHC的手册, 安全语言部分

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. 模块边界控制 - 使用安全语言编译的Haskell代码保证只能访问通过其他模块导出列表公开可用的符号。 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. 如果模块M通过仔细使用其导出列表建立了一些不变量,则使用导入M的安全语言编译的代码保证遵守这些不变量。 Because of this, Template Haskell and GeneralizedNewtypeDeriving are disabled in the safe language as they can be used to violate this property. 因此,模板Haskell和GeneralizedNewtypeDeriving在安全语言中被禁用,因为它们可用于违反此属性。

How can one break a module's invariants using GeneralizedNewtypeDeriving ? 如何使用GeneralizedNewtypeDeriving打破模块的不变量?

Luqui linked to my blog post on the subject. Luqui链接到关于这个主题的博客文章 Basically, GeneralizedNewtypeDeriving as implemented in GHC assumes that a certain kind of isomorphism (namely the operationally irrelevant isomorphism implied by newtype ) implies leibniz equality. 基本上,在GHC中实现的GeneralizedNewtypeDeriving假定某种同构(即newtype隐含的操作上无关的同构)意味着leibniz相等。 This was true in Haskell 98 sort of--but is not at all true in Haskell plus extensions. 这在Haskell 98中是正确的 - 但在Haskell plus扩展中却完全没有

That is, a newtype provides a pair of functions 也就是说,newtype提供了一对函数

a -> b
b -> a

that don't do anything in the core, but it is not okay to conclude 在核心中没有做任何事情,但不能总结

forall f. f a -> f b

because f might be a type function or a GADT. 因为f可能是一个类型函数或一个GADT。 This is the form of equality needed for GeneralizedNewtypeDeriving 这是GeneralizedNewtypeDeriving所需的平等形式

Even in Haskell 98 it breaks module boundries. 即使在Haskell 98中,它也会打破模块边界。 You can have things like 你可以拥有类似的东西

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

which will do bad things... 这会做坏事......

My blog post shows how to implement unsafeCoerce several ways using other extensions (all safe) and GeneralizedNewtypeDeriving. 我的博客文章展示了如何使用其他扩展(all safe)和GeneralizedNewtypeDeriving.实现unsafeCoerce几种方式GeneralizedNewtypeDeriving. I have a better understanding of why this is now, and am much more confident that GeneralizedNewtypeDeriving is unable to produce unsafeCoerce without the "System FC" style extensions (type familes, GADTs). 我对现在的原因有了更好的理解,并且更加确信GeneralizedNewtypeDeriving在没有“System FC”样式扩展(类型为familes,GADT)的情况下无法生成unsafeCoerce Sill, it is unsafe, and should be used with care if at all. Sill,它是不安全的,如果有的话应该小心使用。 My understanding is that Lennart Augustsson (user augustss) implemented it very differently in hbc, and this implementation was safe. 我的理解是Lennart Augustsson(用户augustss)在hbc中实现它的方式非常不同,这种实现是安全的。 A safe implementation would be more limited, and more complicated. 安全的实施将更加有限,而且更加复杂。

UPDATE: With new enough versions of GHC (all problems should be gone as of 7.8.1) GeneralizedNewtypeDeriving is safe because of the new roles system 更新:使用足够新版本的GHC(所有问题都应该从7.8.1开始消失) GeneralizedNewtypeDeriving因为新的角色系统而安全

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM