在GHC中捕获Control-C异常(Haskell) [英] Catching Control-C exception in GHC (Haskell)

查看:80
本文介绍了在GHC中捕获Control-C异常(Haskell)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Haskell中建立了一个非常简单的read-eval-print-loop,它捕获了Control-C(UserInterrupt).但是,每当我编译并运行该程序时,它始终会捕获第一个Control-C,并且总是在退出代码为130的第二个Control-C上中止.我在这之前和之间输入多少行输入都无关紧要Control-C,它总是以这种方式发生.我知道我一定会缺少一些简单的东西...请帮助,谢谢!

I built a really simple read-eval-print-loop in Haskell that catches Control-C (UserInterrupt). However, whenever I compile and run this program, it always catches the first Control-C and always aborts on the second Control-C with exit code 130. It doesn't matter how many lines of input I give it before and between the two Control-Cs, it always happens this way. I know I must be missing something simple... please help, thanks!

注意:这是base-4例外,因此是Control.Exception,而不是Control.OldException.

Note: this is with base-4 exceptions, so Control.Exception and not Control.OldException.

import Control.Exception as E
import System.IO

main :: IO ()
main = do hSetBuffering stdout NoBuffering
          hSetBuffering stdin NoBuffering
          repLoop

repLoop :: IO ()
repLoop
  = do putStr "> "
       line <- interruptible "<interrupted>" getLine
       if line == "exit"
          then putStrLn "goodbye"
          else do putStrLn $ "input was: " ++ line
                  repLoop

interruptible :: a -> IO a -> IO a
interruptible a m
  = E.handleJust f return m
  where
    f UserInterrupt
      = Just a
    f _
      = Nothing

推荐答案

韦虎(Wei Hu)是正确的;当按下第二个Control-C时,Haskell运行时系统会故意中止程序.为了获得人们可能期望的行为:

Wei Hu is correct; the Haskell runtime system deliberately aborts the program when a second control-C is pressed. To get the behavior one might expect:

import Control.Exception as E
import Control.Concurrent
import System.Posix.Signals

main = do
  tid <- myThreadId
  installHandler keyboardSignal (Catch (throwTo tid UserInterrupt)) Nothing
  ... -- rest of program

这篇关于在GHC中捕获Control-C异常(Haskell)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆