私はHaskellのSchemeインタプリタのREPLを実装していますが、UserInterrupt、StackOverflow、HeapOverflowなどの非同期イベントを処理したいと思います。現在の演算UserInterruptが発生してStackOverflowのとHeapOverflowが発生したときに適切なメッセージを出力し、等次のように私はこれを実現:HaskellでのUserInterrupt例外の処理
repl evaluator = forever $ (do
putStr ">>> " >> hFlush stdout
out <- getLine >>= evaluator
if null out
then return()
else putStrLn out)
`catch`
onUserInterrupt
onUserInterrupt UserInterrupt = putStrLn "\nUserInterruption"
onUserInterrupt e = throw e
main = do
interpreter <- getMyLispInterpreter
handle onAbort (repl $ interpreter "stdin")
putStrLn "Exiting..."
onAbort e = do
let x = show (e :: SomeException)
putStrLn $ "\nAborted: " ++ x
一つの例外を除いて期待どおりに動作します。私がインタプリタを起動してCtrl + Z + Enterを押すと、私は次のようになります。
>>> ^Z
Aborted: <stdin>: hGetLine: end of file
Exiting...
これは正しいです。私は入力+インタプリタとはCtrl-Cは、Ctrlキーを押しながらZに続いて開始した場合しかし、私は得る:
>>>
UserInterruption
>>> ^Z
そして、それがハングし、私はもう通訳を使用することはできません。しかし、Ctrl-Cをもう一度押すと、REPLはブロックを解除します。私は多くを検索し、私はそれの理由を理解することはできません。誰も私を説明することはできますか?
多くの感謝!
Ctrl-Z捕らえられている。最初のCtrl-Cはキャプチャされますが、2番目のキャプチャはキャプチャされません。それはおそらく同じ問題です。 完全な動作テストケースでコードを変更できますか? F.e. '通訳者'の代わりに 'return'を使用し、適切なインポートが追加されています。 –