Why can't I force an IO action with seq?

无人久伴 提交于 2019-12-08 17:07:41

问题


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?


回答1:


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.




回答2:


seq evaluated expressions to weak head normal form, which is simply the outermost constructor (or lambda application). The expression print x is already in WHNF, so seq doesn't do anything.

You can get the result you're looking for with the function Debug.Trace.trace.



来源:https://stackoverflow.com/questions/20324446/why-cant-i-force-an-io-action-with-seq

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!