鉴于此代码段:
someFunction x = print x `seq` 1 main = do print (someFunction "test")
代码执行时为什么不print x
打印test
?
$./seq_test 1
如果我替换它error
我可以检查左操作数seq
是否确实被评估.
我怎样才能达到预期的输出:
test 1
只修改someFunction
?
评估一个IO
动作什么都不做.那就对了!
如果您愿意,IO
类型的值只是"指令列表".因此,所有你与该做的seq
是强制程序,以确保1什么应该,如果是真正的动作来完成使用.使用动作与评估无关,它意味着单独将其与main
呼叫绑定.但是,正如你所说,因为这someFunction
是一个非monadic签名的函数,这在这里不可能发生.
你可以做什么...... 但不要是
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 <- someFunction "test" print y
1事实上,即使没有,程序也尽可能确定seq
.只有通过执行操作才能获得更多细节.