haskell - 如果我知道(或合理预期)IO 操作是引用透明的,我可以对其使用 unsafePerformIO 吗?或者还有其他条件吗?

标签 haskell io

假设我有一个函数 foo::String -> IO String,它向 Web 服务发出请求、下载一些数据、解析它并返回一个字符串。我知道,给定相同的请求字符串,Web 服务将始终返回相同的字符串,除非缺少此类互联网连接。这些信息是否足以“安全”使用 unsafePerformIO 并知道它永远不会导致问题?或者我还必须确定其他一些事情吗?

编辑:我考虑这一点的原因是因为我有一个函数 deduce::(String -> String) -> String 它将采用输入函数作为参数并推断出通过使用不同的参数对其进行评估来评估该函数。现在我想推断出此 Web 服务的一些属性,但如果没有 unsafePerformIO,我将不得不大幅更改 deduce,包括将其类型签名更改为 deduce::(String -> IO String) -> String 这意味着我需要更改所有其他我可能想要推断其属性的函数。

最佳答案

不要那样做。 unsafePerformIO 用于绑定(bind)外部原语,进行深度数据结构黑客攻击,有时还建立顶级可变状态。

这听起来很安全,但这是一个坏主意,因为现在您会在意想不到的情况下神奇地发生连接,从而使程序的其余部分在资源使用等方面更难以推理。

正如人们所指出的,如果服务确实总是返回相同的字符串,那么使用 Template Haskell 在编译时一次性发出请求会更安全、更高效。

编辑:好的,我现在看到了这个问题。但您不必更改要推断的其他函数的类型。

如果 f 的类型是 String -> String,那么你总是可以获得 return 。 f::字符串 -> IO 字符串。所以不要搞乱你的其他函数,只需用 return 组合它们即可。现在您可以同样轻松地处理有效和纯代码..

关于haskell - 如果我知道(或合理预期)IO 操作是引用透明的,我可以对其使用 unsafePerformIO 吗?或者还有其他条件吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17367530/

相关文章:

haskell - 比较整数值和浮点值

java - 安卓不保存文件

c++ - 带有 C++ 的 Lua 脚本 : attempt to index global 'io' (a nil value)

asynchronous - 同步读/写端口时避免递归?

Haskell Prelude.read : no parse String

list - FreeMagma 具有恒等式(单位岩浆)是否形成列表结构?

data-structures - 将 Haskell Edison API 和 Core 移植到 F# 有什么好处吗?

haskell - 状态单子(monad) : How to `print` intermediate value in Haskell

multithreading - Julia 的非阻塞读取

java - 如何将文本文件中加载的值与 Jtextfield 中新输入的值相加