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