【问题标题】:How can I keep track of two lists in a function (fold) in OCaml?如何在 OCaml 的函数(折叠)中跟踪两个列表?
【发布时间】:2014-03-28 04:42:03
【问题描述】:

我的这段代码的目标是根据一个简单的条件将一个列表分成两个列表,而我在一个函数中执行此操作时遇到了麻烦。

目前,我折叠传入的列表并说如果条件为真,则添加到列表一。然后我再次弃牌并说如果条件为假,则添加到列表二。这对于较大的列表来说效率非常低,我不知道如何将它组合成一个折叠。

我的工作,低效的代码目前看起来像这样:

let function test old_list_one original_list =
  let list_one = (fold (fun a elt -> 
      if condition = true then elt::a
        else a) old_list_one original_list) in
  let list_two = (fold (fun a elt -> 
      if condition = false then elt::a
            else a) [] original_list) in
do_something list_one list_two

这适用于较小的集合,但在较大的集合上会耗尽资源。我尝试像这样组合折叠:

let function test old_list_one = 
  let list_two = [] in
  let list_one = (fold (fun a elt -> 
      if (condition) = true then elt::a
        else elt::list_two) old_list_one original) in
do_something list_one list_two

OCaml 不跟踪 list_two,它仍然是 []...我怎样才能在 ONE 函数中跟踪 list_two 和 list_one?

另外,对于那些不熟悉 fold 的人 - 它是一个迭代原始元素并将结果累积到 old_list_one 的函数(在本例中)

编辑:使用元组作为累加器就可以了!

【问题讨论】:

  • 这不是“崩溃”,而是编译器错误。顺便说一句,OCaml StdLib 中包含一个功能就是这样做的。 List.partition.
  • 不允许使用除普遍性之外的任何东西,不过感谢您的回复。

标签: ocaml fold


【解决方案1】:

使用一对列表作为累加器参数。累积值可以是任何你喜欢的。

这是它的外观草图:

let f (a, b) x =
    let a' = <calculate> in
    let b' = <calculate> in
    (a', b')

let (list1, list2) = List.fold_left f ([],[]) original_list

【讨论】:

  • 我将如何重新访问列表中的列表?因此,如果我要执行let pair_of_lists = (fold) [solutions;[]] original 并在条件为真时将其添加到累加器的头部,如果条件为假则将其添加到累加器的头部,我不确定如何在折叠完成后重新访问 pair_of_lists。我将使用我正在尝试的代码更新问题,以便您了解我的意思。
  • 已更新。感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-19
  • 1970-01-01
  • 1970-01-01
  • 2020-03-03
  • 1970-01-01
  • 2015-12-16
  • 1970-01-01
相关资源
最近更新 更多