4

我有一个新手问题:在标准 ML 中,您如何捕获“错误:未绑定的变量或构造函数:foo”之类的异常?

我尝试使用以下程序来做到这一点:

(foo())
handle Error msg => ();

但 REPL 抱怨:“错误:非构造函数应用于模式中的参数:错误”

提前致谢。

4

2 回答 2

3

首先它是handle Error => ...(或handle error => ...handle TheSpecificExceptionIWantToCatch => ...),而不是handle Error msg => ...。您只能编写handle Foo msg => ...ifFoo是带有一个参数的构造函数,正如错误消息所暗示的那样,Error它不是。

其次“未绑定变量”是编译错误,不是异常,所以无法捕获。

于 2012-10-18T15:03:11.850 回答
1

只是添加到现有的答案。我注意到 Chao 试图根据它收到的尝试执行代码的消息来“捕捉”一个错误。REPL 中的真正异常消息在该行之后立即报告val it = () : unit,表明它发生在解释阶段之后。此外,在新泽西 v110.76 解释器的标准 ML 中,它在执行时出现如下消息:

uncaught exception ExceptionName raised at: filename.sml:linei.columni-linej.columnj

因此,如果没有看到这些明确的消息,应该发出警报,即没有引发异常,没有双关语的意思。由于问题是如何捕获异常而不是错误,因此我认为必须简要解释异常的机制:

  1. 在代码中的某处,在将使用它的词法范围内,必须定义异常绑定: exception MyExceptionexception MyException2 of String
  2. 在表达式中的某处发现了一个值得中断正常控制流的情况,因此使用以下原语来做到这一点: raise MyExceptionraise (MyException2("Error in foo"))
  3. 可以使用句柄表达式捕获流的异常中断,该句柄表达式在异常构造函数上使用模式匹配并提交和替代表达式进行评估。在这种情况下,表达式e1引发异常并且处理程序返回表达式 e2:e1 handle MyException => e2

有关如何为复杂函数编写干净优雅的异常处理程序以及恢复执行(如果需要)的更多详细信息,请阅读Robert Harper 的在线注释 Programming in Standard ML 的这一页

于 2017-05-02T04:55:55.643 回答