【发布时间】:2014-05-04 15:27:50
【问题描述】:
在我看来,Haskell 中的异常只能在它们被抛出后立即被捕获,并且不像在 Java 或 Python 中那样传播。下面是一个简短的示例:
{-# LANGUAGE DeriveDataTypeable #-}
import System.IO
import Control.Monad
import Control.Exception
import Data.Typeable
data MyException = NoParseException String deriving (Show, Typeable)
instance Exception MyException
-- Prompt consists of two functions:
-- The first converts an output paramter to String being printed to the screen.
-- The second parses user's input.
data Prompt o i = Prompt (o -> String) (String -> i)
-- runPrompt accepts a Prompt and an output parameter. It converts the latter
-- to an output string using the first function passed in Prompt, then runs
-- getline and returns user's input parsed with the second function passed
-- in Prompt.
runPrompt :: Prompt o i -> o -> IO i
runPrompt (Prompt ofun ifun) o = do
putStr (ofun o)
hFlush stdout
liftM ifun getLine
myPrompt = Prompt (const "> ") (\s -> if s == ""
then throw $ NoParseException s
else s)
handleEx :: MyException -> IO String
handleEx (NoParseException s) = return ("Illegal string: " ++ s)
main = catch (runPrompt myPrompt ()) handleEx >>= putStrLn
运行程序后,当您按下 [Enter] 而不输入任何内容时,我应该会在输出中看到:Illegal string:。而是出现:prog: NoParseException ""。现在假设Prompt 类型和runPrompt 函数在模块外部的公共库中定义,并且无法更改以处理传递给Prompt 构造函数的函数中的异常。如何在不更改 runPrompt 的情况下处理异常?
我想过将第三个字段添加到Prompt 以这种方式注入异常处理功能,但对我来说似乎很难看。有更好的选择吗?
【问题讨论】:
标签: haskell exception-handling