【发布时间】:2018-02-04 07:17:18
【问题描述】:
我正在尝试在 OCaml 中编写一个简单的合并排序代码,该代码还删除了重复项。
我写的代码是:
let mergesort l r =
match l with
[] -> []
| [x]-> [x]
| x::xs -> let rec split l3 =
match l3 with
[] -> ([], [])
| [h] -> ([h], [])
| h1::h2::t -> let (left, right) = split t in
(h1::left, h2::right) in
let rec merge l1 l2 r =
match (l1, l2) with
([], []) -> []
| ([a], []) -> [a]
| ([], [a]) -> [a]
| (a1::t1, a2::t2) -> if a1 = a2 then (a1::(merge (t1) t2))
else if r(a1, a2) then (a2::(merge t1 (a2::t2)))
else (a1::(merge (a1::t1) t2)) in
let (l3, l4) = split l in
merge (mergesort l3 r) (mergesort l3 r) r;;
我的合并函数出现以下类型错误:
|(a1::t1, a2::t2) -> 如果 a1 = a2 那么
(a1::(合并 (t1) t2))
错误:此表达式的类型为 'a -> 'b 列表 但是需要一个类型为 'b list
的表达式我不知道为什么会出现此错误,因为合并中的所有分支都返回相同类型的列表。
有人可以帮忙吗?
【问题讨论】:
-
merge接受 3 个参数;你用 2 来调用它。 -
非常感谢,现在错过了这么点小事,感觉自己傻了..
-
我认为当 a1 != a2 对于 案例时,您在合并案例中存在错误。它应该是
(a2::(merge t1 (a1::t2)))和(a1::(merge (a2::t1) t2))。您还可以使用| (a1::t1 as left, a2::t2 as right) -> ...更好地编写此代码,稍后再使用左/右。这保存了为递归调用分配新列表的编译器表单。
标签: ocaml