为什么我不能用seq强制IO动作? [英] Why can't I force an IO action with seq?

查看:134
本文介绍了为什么我不能用seq强制IO动作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出以下代码片段:

  someFunction x = print x`seq` 1 

main = print(someFunctiontest)

为什么不打印x 打印测试代码执行时?

  $。/ seq_test 
1

如果我用 error 替换它,我可以检查 seq

我怎么能达到我的预期输出:



pre> test
1

只修改 someFunction

解决方案

评估 IO 行动什么也不做。这是正确的!



如果您喜欢, IO 类型的值仅仅是指令列表。因此,对于 seq 所做的所有操作都会强制程序确定如果操作应该完成应完成的操作实际上是使用。使用一个动作与评估无关,它意味着将它单调地绑定到 main 调用。但是,正如你所说, someFunction 是一个带有非一次性签名的函数,在这里不会发生。



您可以做什么...... 但不要

  import Foreign 

someFunction x = unsafePerformIO(print x)`seq` 1

实际上它将评估与 IO 执行结合在一起。在Haskell中这通常是一个非常糟糕的主意,因为评估可能以完全不可预见的顺序发生,可能与您想象的发生次数不同(因为编译器假定参照透明度)以及其他混乱情况。



正确的解决方案是将签名更改为monadic:

  someFunction :: Int  - > IO Int 
someFunction x = do
print x
return 1

main = do
y< - someFunctiontest
print y






1 而as它发生了,尽管没有 seq ,程序仍然是尽可能的。任何更多细节只能通过执行操作获得。


Given this code snippet:

someFunction x = print x `seq` 1

main = do print (someFunction "test")

why doesn't the print x print test when the code is executed?

$./seq_test 
1

If I replace it with error I can check that the left operand of seq is indeed evaluated.

How could I achieve my expected output:

test
1

modifying only someFunction?

解决方案

Evaluating an IO action does nothing whatsoever. That's right!

If you like, values of IO type are merely "instruction lists". So all you do with that seq is force the program to be sure1 of what should be done if the action was actually used. And using an action has nothing to do with evaluation, it means monadically binding it to the main call. But since, as you say, someFunction is a function with a non-monadic signature, that can't happen here.

What you can do... but don't, is

import Foreign

someFunction x = unsafePerformIO (print x) `seq` 1

this actually couples evaluation to IO execution. Which normally is a really bad idea in Haskell, since evaluation can happen at completely unforseeable order, possibly a different number of times than you think (because the compiler assumes referential transparency), and other mayhem scenarios.

The correct solution is to change the signature to be monadic:

someFunction :: Int -> IO Int
someFunction x = do
     print x
     return 1

main = do
     y <- someFunction "test"
     print y


1And as it happens, the program is as sure as possible anyway, even without seq. Any more details can only be obtained by executing the action.

这篇关于为什么我不能用seq强制IO动作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆