7

我正在尝试编写一个简单的递归函数来查看列表并返回一对整数。这很容易用 c/c++/java 编写,但我是 ocaml 的新手,所以由于类型冲突很难找到解决方案

它应该像..

let rec test p l = ... ;;
val separate : (’a -> bool) -> ’a list -> int * int = <fun>
test (fun x -> x mod 2 = 0) [-3; 5; 2; -6];; 
- : int * int = (2, 2)

所以问题是我如何递归地返回元组的值..

4

2 回答 2

5

这里的一个问题是您要返回两种不同的类型:空列表的 int 或其他情况下的元组。它需要是其中之一。

另一个问题是您试图将 1 添加到test,但test它是一个函数,而不是一个值。您需要在其他东西上调用 test 才能返回一个值,但即使那样它也应该返回一个元组,您不能将其添加到整数中。

我无法弄清楚您希望代码做什么,但是如果您使用该信息更新您的问题,我可以提供更多帮助。

我的一个猜测是你想计算列表中的正数,在这种情况下你可以这样写:

let rec test l = 
    match l with [] -> 0
   | x::xs -> if x > 0 then 1 + (test xs)
              else test xs;;

更新:由于您已编辑以澄清问题,因此将上述代码修改如下:

let test l =
  let rec test_helper l pos nonpos = 
    match l with [] -> (pos, nonpos)
   | x::xs -> if x > 0 then test_helper xs 1+pos, nonpos
              else test_helper xs pos 1+nonpos
  in test_helper l 0 0;;

在这种情况下,使用累加器有很大帮助。它还使函数尾递归,这总是很好的做法。

于 2010-06-15T05:00:27.360 回答
4

离开 OCaml 有一段时间了,但我认为这可以解决 REALFREE 在评论中的描述

let rec test l = 
  match l with 
      [] -> (0,0) 
    | x::xs -> 
        if x > 0 then match (test xs) with (x,y) -> (x+1, y)
        else  match (test xs) with (x,y) -> (x, y+1);;

您可以使用嵌套的匹配语句来提取元组的片段以进行修改

编辑:我不知道他在下面的评论中提到的语法 Pascal Cuoq,这是这样的代码,它更简洁,更短:

let rec test l = 
  match l with 
      [] -> (0,0) 
    | x::xs -> 
    if x > 0 then let (x,y) = test xs in (x+1, y)
    else let (x,y) = test xs in (x, y+1);;

但是接受的答案仍然要好得多,尤其是尾递归;)。

于 2010-06-15T05:04:27.090 回答