我在hackage上看到了一些代码,发现其中使用了Safe和Trustworthy扩展。
这些扩展的含义是什么(广义或具体)?有没有什么好的经验法则来决定何时使用它们以及何时不使用它们?
我在hackage上看到了一些代码,发现其中使用了Safe和Trustworthy扩展。
这些扩展的含义是什么(广义或具体)?有没有什么好的经验法则来决定何时使用它们以及何时不使用它们?
unsafePerformIO :: IO a -> a
,并且它(旨在)保证您不会以某种方式访问模块的私有函数、数据构造函数等,以防止从中获取访问。简而言之,安全Haskell保证了三件事:
一个安全的模块必须遵循这些限制,并且只能与安全的模块一起工作。当然,一个安全的模块并不意味着它所使用的代码是正确的,或者一个IO
操作不能是恶意的。但是有一些保证,因为如果一个函数的类型没有IO
,那么通常模块就不应该能够以不安全的方式执行IO
。
在安全Haskell中,某些扩展名,如TemplateHaskell
和指定{-# RULES ... #-}
pragma不被允许使用。其他扩展名,如DeriveDataTypeable
是被允许的,但只有当使用deriving
从句生成实例时才允许,因此不生成自定义实例。
然而,有些模块为了正常工作需要使用扩展名。在这种情况下,作者可以将模块标记为Trustworthy
。这意味着作者声称该模块公开了一个安全的API,但内部需要使用一些不安全的扩展、pragma等。编译器因此无法保证其安全性。
这些扩展在文档中有记录:
安全的Haskell扩展引入了以下三个语言标志:XSafe
— 启用安全语言方言,要求GHC保证可信。安全语言方言要求所有导入都是可信的,否则会发生编译错误。
- XTrustworthy
— 表示虽然这个模块可能在内部调用不安全的函数,但模块的作者声称它导出的API不能以不安全的方式使用。这不会启用安全语言,也不会对允许的Haskell代码放置任何限制。可信保证由模块的作者提供,而不是GHC。使用safe关键字的导入语句会在导入的模块没有受信任时导致编译错误。没有关键字的导入语句与通常行为相同,可以导入任何模块,无论是否受信任。
- XUnsafe
— 将正在编译的模块标记为不安全的,以便使用-XSafe编译的模块无法导入该模块。
Safe
对语言施加了一系列限制,例如不使用unsafeIO
,只使用其他被认为是安全的模块。这意味着如果你使用safe
进行编译,Haskell 应该保证的某些方面将被强制执行,并通过防止“技巧”来绕过这些不可能的限制。 - Willem Van OnsemSafe
保护模块吗?如果我已经声明了Safe
,那么Trustworthy
就变得多余了吗?还是同时使用它们是有意义的? - marcosh