System.Timeout
Haskell の練習をして、よく知らない領域を調べていますが、 と を混合しているときに得られる動作を理解できませんでしたSystem.IO.Unsafe
。
でストリームを怠惰に読み取り、getContents
純粋な関数でフィルタリングし、結果を出力しています。典型的なフィルターは次のようになります。
import Data.List(break)
import System.Timeout(timeout)
import System.IO.Unsafe(unsafePerformIO)
main = do
text <- getContents
putStr $ aFilter text
aFilter text = h ++ t where
(h, t) = getUntil "\n" text
getUntil separator text = break (\x -> (separator!!0) == x) text
そして、そのようなフィルターを使用すると、プログラムは期待どおりにすべての stdin を読み取り、stdout に出力します。しかし、私が次のようなことをすると:
aFilter text = result where
l = consumeWithTimeout (getUntil "\n" text)
result = case l of
Nothing -> "Timeout!\n"
Just (h, t) -> h ++ t
consumeWithTimeout (x, y) = unsafePerformIO $! timeout 6 $! deepseq x (return (x, y))
私のプログラムは即座にタイムアウトし、「Timeout!」を出力すると思います。メッセージを表示して閉じます。代わりに、そこでハングして、入力を待ちます。
timeout
関数がプログラムの起動時に評価されると考えるのは間違っていますか? 戻り値の一部をすぐに stdout に書き込み、行を入力するたびにソフトウェアが反応するため、そうなると思います。unsafePerformIO
関数にある種の怠惰を挿入していますか? それとも、の内部に怠惰を挿入していSystem.Timeout
ますか?