[英]Why can't I force an IO action with seq?
鑒於此代碼段:
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
是一個具有非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 <- someFunction "test"
print y
1事實上,即使沒有seq
,程序仍然盡可能確定。 只有通過執行操作才能獲得更多細節。
seq
表達式計算為弱頭正常形式,這只是最外層的構造函數(或lambda應用程序)。 表達式print x
已經在WHNF中,因此seq
不做任何事情。
您可以使用Debug.Trace.trace
函數獲得您正在尋找的結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.