Haskell - 安全可靠的扩展

4

我在hackage上看到了一些代码,发现其中使用了SafeTrustworthy扩展。

这些扩展的含义是什么(广义或具体)?有没有什么好的经验法则来决定何时使用它们以及何时不使用它们?


4
Safe 对语言施加了一系列限制,例如不使用 unsafeIO,只使用其他被认为是安全的模块。这意味着如果你使用 safe 进行编译,Haskell 应该保证的某些方面将被强制执行,并通过防止“技巧”来绕过这些不可能的限制。 - Willem Van Onsem
2
然而,“值得信赖”是由软件包作者提出的一个声明,表明您可以信任该软件包。尽管这有一定的价值,但它实际上并没有限制,因此更像是模块的“注释”。 - Willem Van Onsem
感谢 @WillemVanOnsem。因此,编写新模块时的良好实践(也是最严格的实践)是使用 Safe 保护模块吗?如果我已经声明了 Safe,那么 Trustworthy 就变得多余了吗?还是同时使用它们是有意义的? - marcosh
“安全”比“值得信赖”更强,所以我认为同时使用两者并没有太多的意义。 - Willem Van Onsem
1个回答

7
Safe Haskell本质上是Haskell语言的一个子集。它旨在禁用一些经常使用的“技巧”,例如unsafePerformIO :: IO a -> a,并且它(旨在)保证您不会以某种方式访问模块的私有函数、数据构造函数等,以防止从中获取访问。简而言之,安全Haskell保证了三件事:
  1. 参照透明性;
  2. 模块边界控制; 和
  3. 语义一致性

一个安全的模块必须遵循这些限制,并且只能与安全的模块一起工作。当然,一个安全的模块并不意味着它所使用的代码是正确的,或者一个IO操作不能是恶意的。但是有一些保证,因为如果一个函数的类型没有IO,那么通常模块就不应该能够以不安全的方式执行IO

在安全Haskell中,某些扩展名,如TemplateHaskell和指定{-# RULES ... #-} pragma不被允许使用。其他扩展名,如DeriveDataTypeable是被允许的,但只有当使用deriving从句生成实例时才允许,因此不生成自定义实例。

然而,有些模块为了正常工作需要使用扩展名。在这种情况下,作者可以将模块标记为Trustworthy。这意味着作者声称该模块公开了一个安全的API,但内部需要使用一些不安全的扩展、pragma等。编译器因此无法保证其安全性。

这些扩展在文档中有记录:

安全的Haskell扩展引入了以下三个语言标志:
- XSafe — 启用安全语言方言,要求GHC保证可信。安全语言方言要求所有导入都是可信的,否则会发生编译错误。 - XTrustworthy — 表示虽然这个模块可能在内部调用不安全的函数,但模块的作者声称它导出的API不能以不安全的方式使用。这不会启用安全语言,也不会对允许的Haskell代码放置任何限制。可信保证由模块的作者提供,而不是GHC。使用safe关键字的导入语句会在导入的模块没有受信任时导致编译错误。没有关键字的导入语句与通常行为相同,可以导入任何模块,无论是否受信任。 - XUnsafe — 将正在编译的模块标记为不安全的,以便使用-XSafe编译的模块无法导入该模块。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接