F* 在比赛正文中引发异常

F* Raising Exception in match body

我想在 F* 中创建一个函数来确定列表的最小元素,如果列表为空,我想抛出异常。到目前为止我的代码如下:

module MinList

exception EmptyList

val min_list: list int -> Exn int
let rec min_list l = match l with
  | [] -> raise EmptyList
  | single_el :: [] -> single_el
  | hd :: tl -> min hd (min_list tl)

但是,当我尝试验证文件时,出现以下错误:

mcve.fst(7,10-7,15): (Error 72) Identifier not found: [raise]
1 error was reported (see above)

我该如何解决这个错误?

出现此错误是因为 raise 不是 F* 中的原语,但需要从 FStar.Exn 导入(请参阅 ulib/FStar.Exn.fst),这暴露了此函数 -- raise。只需 opening 这个模块就足够了。代码中还有一个小问题,我也在下面修复了。

这是经过的代码版本:

module MinList

open FStar.Exn

exception EmptyList

val min_list: list int -> Exn int (requires True) (ensures (fun _ -> True))
let rec min_list l = match l with
  | [] -> raise EmptyList
  | single_el :: [] -> single_el
  | hd :: tl -> min hd (min_list tl)

请注意,我还添加了 requiresensures 子句。这是因为 Exn 效果 期望 这些子句来推理其中的代码。但是,如果您的用例恰好具有上述子句(即 true 和 true),那么您可以为此使用方便的同义词 Ex(参见 ulib/FStar.Pervasives.fst)。因此,下面的代码也是有效的,并且 与上面的代码 完全相同。

module MinList

open FStar.Exn

exception EmptyList

val min_list: list int -> Ex int
let rec min_list l = match l with
  | [] -> raise EmptyList
  | single_el :: [] -> single_el
  | hd :: tl -> min hd (min_list tl)