确定哪个整数列表更大

时间:2017-10-20 23:32:05

标签: compiler-errors ocaml

我试图弄清楚哪个整数列表更大。 [1;2;3]的表示实际上是123。 因此给定两个整数列表,我想比较每个元素以确定最后哪个数字更大。返回1如果list1 > list2-1 list1 < list20如果相等。 这是我到目前为止,但当我尝试运行它时,我得到错误,我不明白为什么。我还被要求尽可能以尾递归形式重复进行。这是正确的尾递归吗?

let rec compare' list1 list2 currentOrder = match (list1, list2) with
  | [],[]                     -> 0
  | list1, []                 -> 1
  | [], list2                 -> -1
  | car1::cdr1, car2::cdr2    ->      (*car1 contains the current element and cdr1 contains the rest of the list. Ex car1 = [1], cdr2 = [2;3]*)
    let nextCompare = 
        (
            if cdr1 = [] && cdr2 = [] 
            then 0
            else 1
        )                           
    in 
    (
      if (nextCompare != 0)(*To check if we are not at the end of the list*)
      then (      (*Compare the cars to determine the currentOrder and recursively call with the next number*)
        if car1 > car2
        then (compare' (cdr1 cdr2 1))
        else if car1 < car2
        then (compare' (cdr1 cdr2 -1))
        else (compare' cdr1 cdr2 currentOrder)
      )
      else (*we are at the end of the list so we want to return the current order*)
      (   (*Still need to check in case there is only 1 digit number, because we did not update currentOrder for it to be returned*)
        if car1 > car2
        then 1
        else if car1 < car2
        then -1
        else currentOrder
      )
    )


Printf.printf (compare' [1;2;3] [3;2;1] 0)

1 个答案:

答案 0 :(得分:0)

你遇到的第一个问题是围绕一些函数应用程序(例如(compare' (cdr1 cdr2 1)))的参数的一些额外括号,它告诉OCaml你想用参数{{1}调用cdr1 }和cdr2,然后将结果应用于1。因此,编译器会抱怨您尝试使用列表compare'作为函数。如果您习惯使用括号来运行应用程序,那么这是一个简单的错误。

第二个问题是你有cdr1没有括号,编译器将其解释为将-1应用于二进制1运算符,因此抱怨其结果是正如您所期望的那样,函数而不是int。这种奇怪行为的原因是OCaml支持部分功能应用,这会导致一些歧义。要明确这一点,你只需要用括号括起来:-

最后,代码中有一些冗余,所以我为你简化了一下。更少的代码也意味着更少的地方搞砸,并查看螺丝钉,这在您学习时非常方便:)

(-1)

我不保证这在逻辑上是正确的,但是,它只是对你所写内容的转换(实际上我知道它不正确,但这是一个原因的任务)。 < / p>