Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 如果我知道(或合理预期)IO操作是引用透明的,我可以对其使用unsafePerformIO吗?还是有其他条件?_Haskell_Io - Fatal编程技术网

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

Haskell 如果我知道(或合理预期)IO操作是引用透明的,我可以对其使用unsafePerformIO吗?还是有其他条件?,haskell,io,Haskell,Io,假设我有一个函数foo::String->IO String,它向web服务发出请求,下载一些数据,解析数据,然后返回一个字符串。我知道web服务将始终返回相同的字符串,给定相同的请求字符串,除非缺少类似的internet连接。这些信息是否足以“安全”地使用unsafePerformIO,并知道它永远不会导致问题?或者我还必须确定其他一些事情吗 编辑:我之所以考虑这一点,是因为我有一个函数推断::(String->String)->String,它将输入函数作为参数,并通过使用不同的参数对其求值

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


编辑:我之所以考虑这一点,是因为我有一个函数
推断::(String->String)->String
,它将输入函数作为参数,并通过使用不同的参数对其求值来推断函数的一些属性。现在我想推断这个web服务的一些属性,但是如果没有
unsafePerformIO
,我将不得不实质性地更改
reduce
,包括将其类型签名更改为
reduce::(String->IO String)->String
,这意味着我需要更改所有其他可能要推断其属性的函数。

不要这样做
unsafePerformIO
用于绑定外来原语,进行深层数据结构攻击,有时还用于建立顶级可变状态

这听起来很安全,但这是一个坏主意,因为你现在会有一些连接在你没有预料到的时候奇迹般地出现,从而使你的程序的其余部分在资源使用等方面更难推理

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

编辑:好的,我现在看到问题了。但是你不需要改变你想要推断的其他函数的类型


如果
f
的类型是
String->String
,那么您总是可以得到
返回。f::String->IO String
。因此,不要破坏其他函数,只需使用return编写它们。现在,您可以同样轻松地处理有效代码和纯代码。

鉴于请求可能会失败,正如您自己所说,我怀疑这是一个好主意。我的经验法则是,如果您认为编译器在编译时预计算整个值是可以的,那么您可以使用
不安全的PerformIO
,如果结果从未改变,为什么不将结果硬编码到程序中?或者在编译时使用TH将其插入到程序中。问题类似,上面的答案显示了如何使用TH在编译时加载
IO
资源。我想你误解了我说的它“返回相同的字符串”。我的意思是,给定相同的输入,它总是返回相同的字符串,并且在程序的整个生命周期中将使用许多不同的输入。我在原始问题中添加了更多关于我到底在做什么的细节。@Drew我仍然建议您使用
IO
。使用起来并不难。