Ocaml 函数取消组合序列,而不使用append

Ocaml 函数取消组合序列,而不使用append,ocaml,Ocaml,我想编写一个函数,将一个偶数序列拆分为一个偶数序列,代码如下: let uncombine s = let rec ayx s1 s2 sr = match s () with | Nil -> s1, s2 | Cons(((e1, e2), sr) -> aux (append s1 (singleton e1)) (append s2 (s(singleton e2)) sr in aux nil nil 由于复杂性,我不想使用ap

我想编写一个函数,将一个偶数序列拆分为一个偶数序列,代码如下:

let uncombine s = 
  let rec ayx s1 s2 sr = 
    match s () with 
    | Nil -> s1, s2
    | Cons(((e1, e2), sr) ->  aux  (append s1 (singleton e1)) (append s2 (s(singleton e2)) sr 
  in aux nil nil

由于复杂性,我不想使用append而不是递归终端函数。我想您要做的是:

let uncombine s =
  let rec aux sr =
    match sr with
    | Nil -> Nil, Nil
    | Cons ((e1, e2), sr) ->
      let s1, s2 = aux sr in
      Cons (e1, s1), Cons (e2, s2)
  in
  aux (s ())

当然,您也可以编写一个尾部递归函数,并在最后将其反转。您不会获得最佳性能,但也不会冒堆栈溢出的风险。

您编写的代码并没有达到您声称的效果。不清楚您是否需要递归终端解决方案,以及保持顺序是否重要。我对其进行了测试,它完全符合我的要求是的顺序很重要您定义了一个函数ayx,该函数从未使用过,但使用了一个名为aux的函数。这个函数使用函数s作为参数,它在第一次使用时使用一个单位,然后我假定在第二次使用时使用一个列表。括号不匹配。此外,函数ayx不依赖于尾部递归函数的输入sr向后构造列表并在最后反转。或者只使用List.split。但我认为尾部递归是目标,至少这是我从不是递归终端函数中得到的。递归终端是尾部递归法语名称的直接翻译。由于括号中没有一个,我怀疑OP不想要这样的解决方案。List.split可以处理列表,但这不是我们正在处理的类型,或者我遗漏了什么吗?type'at=Nil | Cons of'a*'at是学校引入列表的方式。它只是一个没有语法糖的列表。这让我觉得这是一个家庭作业问题。我同意OP一直将他们的家庭作业作为问题发布。我也同意这是一个清单的实施。但我不明白如何使用List.split,因为它需要一个列表作为输入,而不是此处使用的自定义类型。我不会使用自定义类型,因为列表已经实现了该确切类型,并且已经具有所有有用的支持方法。