两个连续的递归调用OCaml

时间:2018-10-05 18:26:21

标签: ocaml

我具有以下功能:

let extract n l =
    let rec aux acc pro = function
         |[]   -> acc
         |a::b -> if (List.length pro) = n then aux (pro::acc) [] (a::b) else aux acc (a::pro) b; aux acc (pro) b
    in aux [] [] l

正如您在第二个测试案例中的模式匹配中所看到的,我正在调用两次函数。可能吗 ?

因此可能具有这种功能:

let rec some_function = function
   | [] ->[]
   | a::b -> some_function b; some_function b (*so I am calling two times the function in a single test*)

我问这个问题是因为这里有以下警告:

File "main.ml", line 4, characters 48-72:
Warning 10: this expression should have type unit.

因此在我两次调用递归函数的确切位置出现了问题。 可能是因为我正在使用;,但是在这种情况下,如何分隔这两个调用?

谢谢!

2 个答案:

答案 0 :(得分:1)

要在FlorianWeimer的答案中添加一些有关您的错误消息的信息。

Warning 10: this expression should have type unit.

OCaml是强类型的。因此,如果一个函数返回一个整数或一个列表,而您对它不执行任何操作,它将想知道发生了什么并警告您。

print_int 5;这样的函数调用将返回(),其类型为unit。基本上,这意味着它什么也不返回,因为您不是将其称为 compute ,而是调用 do 。它已经完成了这件事,现在又返回并继续前进。

但是像float_of_int 5;这样的函数调用会返回一个值(浮点数5.0)。您(可能)没有称它为某事,而是为 compute 做某事,它返回的是您感兴趣的东西。像3+6;这样的算术表达式,或者像10;"abc";[];这样的简单值也是如此。

这就是为什么,如果您编写其中一个具有值的东西而没有使用该值(在赋值中或作为另一个函数的参数),OCaml会警告您。它告诉您“我计算了一些我没有分配,没有返回的东西,并且没有将其用作其他东西的参数。通常,unit类型的东西是唯一的类似东西。确定您的代码中没有错误?”

有时候,您知道自己在做什么,并且不想收到该警告。在这种情况下,您可以调用ignore函数。 ignore将采取任何措施并将其忽略,返回()。例如,ignore 5;ignore (float_of_int 10);不会抛出用5;float_of_int 10;会收到的“此表达式应具有类型单位”警告。

答案 1 :(得分:0)

从某种意义上说,编译器可以接受它,但是只有对结果执行某些操作(或者该函数有副作用)时,它才有意义。两个函数调用的经典示例是斐波那契数列的递归计算:

let rec fib = function
  | 0 -> 0
  | 1 -> 1
  | n -> fib (n - 1) + fib (n - 2)