简体   繁体   English

类型不匹配的OCaml?

[英]Type mismatch OCaml?

I have a problem, OCaml thinks the a and s parameters of my function are unit list s, but they have to be 'a list and string respectively. 我有一个问题,OCaml认为我函数的as参数是unit list ,但它们必须分别是'a liststring The function has to output the list elements separated by the given separator. 该函数必须输出由给定分隔符分隔的列表元素。

The result has to be a string, with the below input: "This-is-label" 结果必须是一个字符串,并带有以下输入:“ This-is-label”

PS I know about match, but I can`t use it PS:我知道比赛,但是我不能使用它

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"] "-";;

It seems you expect this expression to be a string: 看来您希望此表达式是一个字符串:

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

However, the meaning of the ; 但是, ;的含义; operator is to evaluate the expression at the left and then ignore its value. 运算符是对左侧的表达式求值,然后忽略其值。 (It is also considered bad form if the type isn't unit.) Then evaluate the expression at the right, which is the value of the expression. (如果类型不是单位,则它也被认为是不好的形式。)然后,评估右边的表达式,即表达式的值。

So this expression says to evaluate List.hd a , then forget the value. 因此,该表达式表示要评估List.hd a ,然后忘记该值。 Then evaluate s , then forget the value. 然后计算s ,然后忘记该值。 Then evaluate the recursive call. 然后评估递归调用。

So the first problem is to assemble these things into a string. 因此,第一个问题是将这些东西组装成一个字符串。

The ^ operator concatenates two strings. ^运算符连接两个字符串。 So something like this is closer to what you want: 所以像这样的东西更接近你想要的:

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

Note that you need to parenthesize the call to List.tl . 请注意,您需要在对List.tl的调用中加上括号。 Otherwise it looks like two separate parameters to function1 . 否则,它看起来像是function1两个单独的参数。

The problem in your code are missing () around List.tl a in the recursive call. 您的代码中的问题在递归调用中的List.tl a周围缺少()。 Also ^ must be used to concatenate the strings instead of ; 另外,必须使用^代替字符串来连接字符串; . The code is still very un-ocaml like. 该代码仍然非常不熟悉。

There really is no good way to do this without pattern matching. 如果没有模式匹配,实际上是没有任何好的方法。 If this is a homework assignment where you aren't allowed to use pattern matching then please give your instructor a big kick in the behind. 如果这是一项不允许您使用模式匹配的家庭作业,请给您的老师一个很大的帮助。

The order of arguments also would be better the other way around, have the separator as first argument. 相反,参数的顺序也更好,将分隔符作为第一个参数。 That way you can bind the function to a separator and reuse it many times. 这样,您可以将函数绑定到分隔符并多次重复使用。

Two alternative implementations: 两种替代实现:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM