OCaml 预计有类型单元

Sai*_*aik 2 ocaml

当尝试在 中运行以下函数时OCaml

let rec func1 o_list =
    match o_list with
    | [] -> []
    | h::t -> let (nt,inner_list) = h in
      if check_if_clear inner_list then
        [nt,inner_list]::clear_rules
      func1 t
;;
Run Code Online (Sandbox Code Playgroud)

程序输出错误

字符 139-141:[nt,inner_list]::clear_rules

错误:此变体表达式应具有类型unit 构造函数::不属于类型unit

您还可以假设该函数现在 check_if_clear总是返回。是一个pair列表,pair本身包含一个元素和一个列表。所以它是这样的,一开始只是一个空列表。trueo_list[ 'x , ['a,'b,'c]]clear_rules

Rei*_*nds 6

您原来的示例似乎在 后缺少分号clear_rules。一旦插入并带有附加功能的存根,错误消息就可以重现。其原因有以下几点:

thenif 表达式的分支

if check_if_clear inner_list then
    [nt,inner_list]::clear_rules
Run Code Online (Sandbox Code Playgroud)

返回类型的值('nt_type, 'inner_list_type) list list;这是因为[nt, inner_list]构造该对的单个项目列表(nt, inner_list),然后 cons 运算符::使其成为列表的头部。因此,then分支返回非单位类型。

相反,else分支(由于不存在)具有类型单元(即没有实际值)。then但在 OCaml 中,表达式的and分支的类型else必须匹配(即属于相同类型或公共超类型的子类型);因此,没有分支的 if 表达式始终具有类型 unit,此类表达式的分支else也是如此。then因为它不适合您的情况,所以编译器会通过注意到 cons 运算符::具有与其推断的单位类型不同的类型(它创建一个列表并返回它)来告诉您(以迂回的方式)。

从您的评论中我怀疑您的意图不是创建列表,而是执行一些具有副作用的操作。为此,您可能需要以不同的方式编写该操作。