我正在用Haskell写一个REPL。其基本思想如下:
repl :: IO ()
repl = do putStr ">> "
hFlush stdout
input <- getLine
...
repl
字符串
我想模仿一些GHCi行为,当按下CTRL-C时,REPL丢弃当前行并开始一个新的空行供用户输入。我想到SIGINT引发了AsyncException
的UserInterrupt
,这可以由catch
处理。因此,在输入行上进行一些修改:
repl :: IO ()
repl = do putStr ">> "
hFlush stdout
input <- getLine `catch` handleCC
repl
handleCC :: AsyncException -> IO String
handleCC _ = do putStr "\n>> "
hFlush stdout
getLine `catch` handleCC
型
在handleCC
中,AsyncException
将再次通过递归处理,所以我肯定可以无限次中断REPL,对吗?
我当然不能第二CTRL-C仍然终止REPL。但为什么呢?
>> something^C
>> another^C
[Process exited 130]
型
1条答案
按热度按时间x6yk4ghg1#
在深入挖掘之后,我相信我可以得出结论,
catch
不能正确地处理异步异常,try
或类似的也不能。mask
似乎是一个潜在的解决方案,但我发现它的用法有点复杂,即使在文档中也是如此。This answer通过使用POSIX API安装持久信号处理程序提供了一个工作解决方案。与我的代码集成:
字符串