10

このコード スニペットを考えると:

someFunction x = print x `seq` 1

main = do print (someFunction "test")

コードが実行されたときにprint x印刷されないのはなぜですか?test

$./seq_test 
1

に置き換えるとerror、の左オペランドseq 実際に評価されていることを確認できます。

どうすれば期待される出力を達成できますか:

test
1

変更のみsomeFunction

4

2 に答える 2

12

アクションを評価IOしても何も起こりません。それは正しい!

必要に応じて、型の値IOは単なる「命令リスト」です。したがって、アクションが実際に使用された場合に行うべきことseqプログラムに確認させるだけです。そして、アクションを使用することは評価とは何の関係もありません。それは、それを呼び出しにモナド的にバインドすることを意味します。しかし、あなたが言うように、は非モナド署名を持つ関数であるため、ここでは起こり得ません。mainsomeFunction

あなたができること...しかししないことは

import Foreign

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

これは実際に評価をIO実行に結び付けます。通常、これは Haskell では非常に悪い考えです。評価は完全に予測不可能な順序で発生する可能性があり、(コンパイラが参照透過性を想定しているため) 想定とは異なる回数になる可能性があるためです。

正しい解決策は、署名をモナドに変更することです。

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

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

1そしてたまたま、このプログラムは、 がなくても可能な限り確実ですseq。これ以上の詳細は、アクションを実行することによってのみ取得できます。

于 2013-12-02T09:30:09.377 に答える