【问题标题】:Ocaml loop tail recursionOcaml循环尾递归
【发布时间】:2017-09-30 18:59:51
【问题描述】:

我已经基本完成了我的作业,因为我只需要一定数量的工作测试示例。我唯一的问题是我无法弄清楚为什么这不起作用,我想知道我的理智。

let list_helper (x: 'a -> bool) head = if (x head) then true else false
let take_while (x: 'a -> bool) lst = 
    let rec take_while_helper x lst acc = match lst with
    | [] -> []
    | h::t -> if list_helper x h then take_while_helper x t (h::acc) else acc in take_while_helper x lst []
  • take_while (fun _ -> true) [1; 2; 3] 应该评估为 [1; 2; 3]。这个不行。
  • take_while ((=) "a") ["a"; "a"; "b"; "a"] 应该评估为 ["a"; "a"]。按预期工作。
  • take_while (fun _ -> false) ["say"; "anything"] 应该评估为 []。按预期工作。

最后两个测试用例有效,但第一个无效。我做了另一个类似的功能,但它再次不起作用。看来我的函数不能很好地处理整数,我不知道为什么。我想知道为什么它的行为不正确,因为我在逻辑上通过它并且似乎它应该工作。也许我遗漏了一些关于整数和列表的内容。

【问题讨论】:

  • 你会得到什么输出?为什么会这样?
  • 顺便说一句,list_helper x h 相当于x hif … then true else false 是布尔值的标识函数 - 只需将其删除即可。
  • 除了不使用第一个测试用例之外,我认为它也不适用于take_while (fun x -> x < "c") ["a"; "b"; "c"; "d"]
  • 是的,Harald 所说的忘记归还累加器

标签: list ocaml tail-recursion


【解决方案1】:

如果列表为空,您还必须返回累加器。而且您必须反转结果,因为您以错误的顺序将元素添加到累加器中。

所以你的函数可能看起来像

let take_while (x: 'a -> bool) lst = 
  let rec take_while_helper lst acc = match lst with
  | [] -> acc
  | h::t -> if x h then (take_while_helper t (h::acc)) else acc
  in List.rev (take_while_helper lst [])

【讨论】:

  • 啊,我知道我忘记归还累加器了,谢谢,我现在知道为什么错了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-07
  • 2013-11-15
  • 1970-01-01
  • 1970-01-01
  • 2016-06-06
  • 1970-01-01
相关资源
最近更新 更多