OCaml预计有类型单位

时间:2016-01-19 21:44:48

标签: 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
;;

程序输出错误

  

人物139-141:       [NT,inner_list] :: clear_rules

     

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

此外,您可以假设函数check_if_clear现在总是返回trueo_list是一对配对列表,它本身包含一个元素和一个列表。 所以它就像这样[ 'x , ['a,'b,'c]]clear_rules最初只是一个空列表。

2 个答案:

答案 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中,表达式的thenelse分支的类型必须匹配(即,具有相同类型或常见超类型的子类型);因此,没有else分支的if表达式总是具有类型单元,这样的表达式的then分支也是如此。因为它不是你的情况,编译器通过注意cons运算符::具有不同的类型(它创建一个列表并返回它)而不是单元,告诉你(以一种迂回的方式)它推断出的类型。

我怀疑你的意见是你的意图不是创建一个列表,而是执行一些带有副作用的动作。为此,您可能需要以不同的方式编写该操作。