首页 文章

OCaml预计有类型单位

提问于
浏览
2

尝试在 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 起初只是一个空列表 .

2 回答

  • 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
    ;;
    
  • 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运算符 :: 具有不同的类型(它创建一个列表并返回它)而不是它所推断的单元类型,告诉你(以一种环形方式) .

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

相关问题