【问题标题】:Ocaml Type error in merge sort program合并排序程序中的 Ocaml 类型错误
【发布时间】: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


【解决方案1】:

您的代码中有几个问题:

  • 在 cmets 中提到,merge 函数有 3 个参数,但你用 2 个参数调用它,
  • mergesort 函数被递归调用,但它没有被声明为recursive。

这是existing implementation

【讨论】:

  • splitmerge 声明为顶级函数而不是本地定义也可能更有意义。
  • 确实,如果这些功能可能在某个地方再次出现的话。
猜你喜欢
  • 2016-02-05
  • 1970-01-01
  • 1970-01-01
  • 2018-10-13
  • 2013-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多