【问题标题】:Type mismatch OCaml?类型不匹配 OCaml?
【发布时间】:2019-03-27 06:09:41
【问题描述】:

我有一个问题,OCaml 认为我函数的as 参数是unit lists,但它们必须分别是'a liststring。该函数必须输出由给定分隔符分隔的列表元素。

结果必须是一个字符串,输入如下:“This-is-label”

附:我知道match,但我不能用它

let rec function1 a s =
    if a = [] then failwith "Empty list" else 
    if List.tl a = [] then List.hd a else
    if List.tl a != [] then List.hd a; s; function1 List.tl a s
    ;;

function1 ["This"; "is"; "label"] "-";;

【问题讨论】:

  • 我建议你试试pattern matching
  • ocaml 如何从中获得unit list?我预计会出现This expression has type 'a list -> 'a list but an expression was expected of type 'b list 的错误。是不是因为; 期望第一个表达式返回单位?

标签: list ocaml typeerror


【解决方案1】:

您似乎希望这个表达式是一个字符串:

List.hd a; s; function1 List.tl a s

但是,; 运算符的含义是对左边的表达式求值,然后忽略它的值。 (如果类型不是单位,它也被认为是错误的形式。)然后计算右边的表达式,这是表达式的值。

所以这个表达式说要评估List.hd a,然后忘记这个值。然后评估s,然后忘记值。然后评估递归调用。

所以第一个问题是将这些东西组装成一个字符串。

^ 运算符连接两个字符串。所以这样的东西更接近你想要的:

List.hd a ^ s ^ function1 (List.tl a) s

请注意,您需要在对List.tl 的调用中加上括号。否则,function1 看起来像是两个单独的参数。

【讨论】:

    【解决方案2】:

    您的代码中的问题在递归调用中缺少 List.tl a 周围的 ()。此外,^ 必须用于连接字符串,而不是 ;。代码仍然很不像ocaml。

    如果没有模式匹配,真的没有什么好方法可以做到这一点。如果这是一项不允许您使用模式匹配的家庭作业,那么请在背后给您的老师一个大力支持。

    反过来,参数的顺序也会更好,将分隔符作为第一个参数。这样您就可以将函数绑定到分隔符并多次重复使用。

    两种替代实现:

    let rec join s = function
    | [] -> "" (* or failwith "Empty list" if you insist *)
    | [x] -> x
    | x::xs -> x ^ s ^ join s xs
    
    let join s a =
      let (res, _) =
        List.fold_left
          (fun (acc, sep) x -> (x ^ sep ^ acc, s))
          ("", "")
          a
       in
       res
    

    【讨论】:

      猜你喜欢
      • 2015-05-28
      • 2012-01-12
      • 1970-01-01
      • 1970-01-01
      • 2016-01-17
      • 2012-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多