我有一个问题,OCaml认为我函数的a
和s
参数是unit list
,但是它们必须是'a list
和string
分别。该功能必须输出由给定分隔符分隔的列表元素。
结果必须为字符串,并带有以下输入:“ This-is-label”
P.S。我知道比赛,但是我不能使用
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"] "-";;
答案 0 :(得分:2)
似乎您希望此表达式为字符串:
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
的两个单独的参数。
答案 1 :(得分:0)
您的代码中的问题在递归调用中List.tl a
周围缺少()。另外,必须使用^
代替;
来连接字符串。该代码仍然非常不熟悉。
如果没有模式匹配,确实没有任何好的方法。如果这是一项不允许您使用模式匹配的家庭作业,请给您的老师一个很大的帮助。
相反,参数的顺序也更好,将分隔符作为第一个参数。这样,您可以将函数绑定到分隔符,然后多次重用。
两个替代实现:
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