假设我有一个函数foo :: String -> IO String
,它向Web服务发出请求,下载一些数据,解析它并返回一个字符串。我知道,在给定相同的请求字符串的情况下,Web服务将始终返回相同的字符串,除非缺少某种类型的互联网连接。这是否足以“安全”使用unsafePerformIO
,并知道它永远不会导致问题?或者我必须确定其他一些事情吗?
编辑:我考虑这个的原因是因为我有一个函数deduce :: (String -> String) -> String
,它将输入函数作为参数,并通过用不同的参数进行评估来推导出函数的某些属性。现在我想推断出这个Web服务的一些属性,但没有unsafePerformIO
我将不得不大幅改变deduce
,包括将其类型签名更改为deduce :: (String -> IO String) -> String
,这意味着我需要更改所有其他函数我可能想要推断出属性。
答案 0 :(得分:11)
不要那样做。 unsafePerformIO
用于绑定外来原语,执行深层数据结构黑客攻击,有时建立顶级可变状态。
这听起来很安全,但这是一个糟糕的主意,因为当你不期望它们时,你现在会神奇地发生连接,从而使你的程序的其余部分在资源使用方面更难以推理等。 / p>
正如大家所知,如果服务确实总是返回相同的字符串,那么使用Template Haskell在编译时一劳永逸地发出请求会更安全,更有效。
编辑:好的,我现在看到了这个问题。但是你不必改变你想要推断的其他函数的类型。
如果f
的类型为String -> String
,则您始终可以获得return . f :: String -> IO String
。所以不要搞砸你的其他功能,只需用返回来组合它们。现在,您可以轻松地处理有效和纯粹的代码..