2012-04-04 35 views
7

最近我一直在阅读约unsafePerformIO,我想问你一些问题。我确定一个真正的语言应该能够与外部环境进行交互,因此unsafePerformIO有些合理。如何知道一个明显纯粹的Haskell接口隐藏不安全的操作?

然而,据我所知,我不知道有没有快速的方法来知道,如果没有检查代码来寻找unsafePerformIO的调用,看起来纯粹的(从类型判断的)接口/库是否真的很纯(文件可以省略提及它)。 我知道它应该只在确定参照透明度得到保证时才使用,但我想知道它。

+3

“我知道它应该只在确定参考透明度得到保证时才使用”。只能在内部操作不能以任何合理的方式泄漏到外面的时候使用,也就是说当无法辨别引擎盖下是否有这样的东西时。 – leftaroundabout 2012-04-04 22:38:38

+1

顺便说一句,使用'unsafePerformIO'与外部环境进行交互正是你不允许做的事情。所有的效果都应该在你的代码内部 - 比如在幕后使用可变变量来实现记忆。 – ehird 2012-04-04 23:04:00

+0

@ehird:感谢您的进一步解释,但是当我编写“环境”时,我的意思是更广泛的含义,其中还包括外部(非哈希库尔)库。我没有考虑用户交互。 – 2012-04-04 23:09:03

回答

10

没有检查源代码是没有办法的。但这并不难,因为Haddock直接在文档中直接提供了语法高亮的定义。举例来说,请参见this page上定义右侧的“源”链接。

Safe Haskell在这里是相关的;它用于在您想禁止使用不安全功能的情况下编译Haskell代码。如果一个模块使用不安全的模块(如System.IO.Unsafe),并且没有明确标记为Trustworthy,它将继承其不安全状态。但使用unsafePerformIO的模块通常会安全地使用它,因此声明自己为Trustworthy

+0

谢谢你,所以它就像我想的那样...源代码或什么也不是。至少,尽管程序员再次保证,安全Haskell可能会帮助自动识别一些不安全的模块。 – 2012-04-04 22:54:45

5

在你想的情况下,使用unsafePerformIO是不合理的。 documentation for unsafePerformIO解释了这一点:它仅用于执行者可以证明没有办法打破参考透明度,即“纯功能性”语义的情况。也就是说,如果任何人使用unsafePerformIO的方式,一个纯粹的功能程序可以检测到它(例如,写一个函数的结果不仅仅取决于它的参数),那么这是一个不允许的用法。

如果遇到这种情况,最可能的可能是您发现了一个错误。

+2

从这个问题:“我知道只有当你确定参照透明度是有保证的时候才应该使用它,但我想知道它。” – ehird 2012-04-04 22:43:12

+0

@sacundium:你说得对,我已经看到'unsafePerformIO'的文档页面,但这只是一个规则,我不能确定程序员是否有参照透明度的证明:) – 2012-04-04 22:44:10