尝试在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
;;
程序输出错误
人物139-141: [NT,inner_list] :: clear_rules
错误:此变体表达式应具有类型单位 构造函数::不属于类型单元
此外,您可以假设函数check_if_clear
现在总是返回true
。
o_list
是一对配对列表,它本身包含一个元素和一个列表。
所以它就像这样[ 'x , ['a,'b,'c]]
而clear_rules
最初只是一个空列表。
答案 0 :(得分:2)
我设法以另一种方式解决了我面临的问题,而不是尝试使用一些外部列表,我让我的函数返回所需的列表。这是代码
let rec func1 o_list clear_list =
match o_list with
| [] -> clear_list
| h::t -> let (nt,inner_list) = h in
if check_if_clear inner_list then
func1 t ([nt,inner_list]::clear_list)
else
func1 t clear_list
;;
答案 1 :(得分:2)
您的原始示例似乎在clear_rules
之后缺少分号。一旦插入并具有用于附加功能的存根,则错误消息是可再现的。它有以下原因:
if-expression
的then
分支
if check_if_clear inner_list then
[nt,inner_list]::clear_rules
返回('nt_type, 'inner_list_type) list list
类型的值;这是因为[nt, inner_list]
构造了对(nt, inner_list)
的单个项目列表,然后cons运算符::
使其成为列表的头部。因此,then
分支返回非单位类型。
相反,else
分支(由于不存在)具有类型单位(即没有实际值)。但是在OCaml中,表达式的then
和else
分支的类型必须匹配(即,具有相同类型或常见超类型的子类型);因此,没有else
分支的if表达式总是具有类型单元,这样的表达式的then
分支也是如此。因为它不是你的情况,编译器通过注意cons运算符::
具有不同的类型(它创建一个列表并返回它)而不是单元,告诉你(以一种迂回的方式)它推断出的类型。
我怀疑你的意见是你的意图不是创建一个列表,而是执行一些带有副作用的动作。为此,您可能需要以不同的方式编写该操作。