OCaml:对大型程序使用“ try”和“ with”

时间:2019-05-31 23:02:21

标签: exception ocaml

假设您有一系列可能引发异常的表达式。如果是这样,则您希望进行一些漫长的过程。如果不是这样,您希望进行其他漫长的过程。在命令式语言中,您通常可以执行

之类的操作
try:
    ...
except:
    ...

但我似乎无法在OCaml中重现此内容,因为似乎您一次只能检查一个表达式是否出现异常。我也看不到如何使用该值(如果存在)或执行其他操作(如果不存在)。

举一个更具体的例子,例如:我有一个函数list_max,该函数返回非空列表的最大值,如果为空,则引发异常。假设我有一个列表,并且想断言它的最大值为4,但是我错了,它实际上是一个空列表。我似乎无法从所找到的解释中正确理解语法。我已经尝试了以下方法和许多排列方式:

try (list_max [])
with
| Failure s -> -1
| _ -> assert (list_max [] = 4);;

[Edit:而不是上面的人为例子,也许更有意义的例子是:假设我要对该list_max函数进行单元测试。我知道我能做到

assert ( (list_max [1;2;3] = 3 );;

但是我该如何测试list_max正确地在一个空列表上引发异常?]

1 个答案:

答案 0 :(得分:2)

您可以在try表达式中执行断言,只要它引发您没有捕获的异常即可。任何其他异常(例如Assert_failure)都将通过。

try assert (list_max [] = 4) with
| Failure s -> -1

但是assert返回unit,因此无论如何这都是类型错误。

一种替代方法是使用exception case in pattern matching

match list_max [] with
| exception (Failure _) -> -1
| _ -> assert (list_max [] = 4)

(这仍然有类型错误)

最后,您可能希望使用optionresult类型而不是异常,因为它们更加安全。然后,编译器不会让您忘记错误条件。如果list_max返回了option,则应该是:

match list_max [] with
| None -> -1
| Some _ -> assert (list_max [] = 4)

(尽管仍然有类型错误)