3

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

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

4

1 回答 1

11

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

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

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

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

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

于 2013-06-28T16:00:59.387 回答