我有一个功能
import System.Exit
exit_and_report_type_mismatch :: String -> IO ExitCode
exit_and_report_type_mismatch error_message = do
putStrLn error_message
exitFailure
Run Code Online (Sandbox Code Playgroud)
和另一部分像这样
interpret_expr :: Vars -> Expr -> Val
interpret_expr vars (Plus (ConsE _ _) (NumE _)) = exit_and_report_type_mismatch "Type Error: Can only concatenate list (not int) to list"
Run Code Online (Sandbox Code Playgroud)
Haskell向我抱怨它期待类型Val(我定义的另一种数据类型),但实际上它接收类型IO Exitcode.足够公平 - exit_and_report_mismatch返回的IO ExitCode不是Val.
如何从"exit_and_report_type_mismatch"中完全中止Haskell程序?我已经阅读了一些关于Haskell异常的内容,但是解释要么没有意义,要么提到必须从main函数调用ExitWith,这不是一个选项.
Ant*_*sky 10
这error是为了什么.从文档:
例如:
zsh% runhaskell <<<'main = putStrLn (error "Message") >> print "Not reached."'
runghcXXXX7729.hs: Message
Run Code Online (Sandbox Code Playgroud)
putStrLn忽略效果,并且一旦error需要生成的值,程序就会终止(延迟评估意味着只是放在error某处不会立即导致错误;正如您可能或可能不期望的那样,不会let x = error "Message" in putStrLn "Printed"导致错误).它是可以捕获这些异常与功能Control.Exception.Base,如catch,但我从来没有这样做,也没看到这件事.
另外,作为最后一点,请考虑避免使用error.在可能的情况下,最好避免使用部分函数(未在整个输入域中定义的函数),因为使用总函数提供的更强保证更容易推理代码.当总函数f :: A -> B真正意味着"函数f返回类型B" 时,这是很好的; 对于部分函数,f :: A -> B仅表示" 如果函数f返回,则返回的类型为B".在你的情况下,这可能意味着有类似的类型interpretExpr :: Vars -> Expr -> Either RuntimeError Val,或适当同构的东西(在最简单的情况下,也许data Result = Error String | Value Val,和interpretExpr :: Vars -> Expr -> Result).