当尝试在 中运行以下函数时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本身包含一个元素和一个列表。所以它是这样的,一开始只是一个空列表。true
o_list
[ 'x , ['a,'b,'c]]
clear_rules
您原来的示例似乎在 后缺少分号clear_rules
。一旦插入并带有附加功能的存根,错误消息就可以重现。其原因有以下几点:
then
if 表达式的分支
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 运算符::
具有与其推断的单位类型不同的类型(它创建一个列表并返回它)来告诉您(以迂回的方式)。
从您的评论中我怀疑您的意图不是创建列表,而是执行一些具有副作用的操作。为此,您可能需要以不同的方式编写该操作。