【问题标题】:ocaml recursive pattern matchingocaml 递归模式匹配
【发布时间】:2011-03-03 19:46:21
【问题描述】:

我正在尝试编写一个简单的递归函数来查看列表并返回一对整数。这很容易用 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)

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

【问题讨论】:

  • 你能提供更多关于这个函数应该返回什么的细节吗?这对整数代表什么?
  • 所以它应该返回一对整数作为 (x,y) ,它是 ocaml 中的元组,我面临的唯一问题是元组计算.. 所以它就像,如果列表的元素更少then some number then (x+1, y) else (x, y+1) 所以返回值将是 (x,y) 其中 x 是大于某个数字且 y 小于

标签: ocaml matching


【解决方案1】:

这里的一个问题是您要返回两种不同的类型:一个 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;;

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

【讨论】:

  • 如何修改为前向递归?
【解决方案2】:

暂时远离 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);;

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

【讨论】:

  • 如果你正在写一个带有单一模式的match .. with ..,你可以使用let来代替:let x, y = test xs in ...
猜你喜欢
  • 2019-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-11
  • 2017-01-26
  • 2015-09-12
相关资源
最近更新 更多