Function 如何编写使用尾部递归添加列表元素的函数?

Function 如何编写使用尾部递归添加列表元素的函数?,function,functional-programming,ocaml,Function,Functional Programming,Ocaml,我需要用OCaml编写一个函数,在两个不同的递归中添加两个列表的元素:simple和tail。我做了一个简单的: let rec add1 a b = match (a, b) with ([], []) -> [] | (head1::tail1, []) -> head1 :: add1 tail1 [] | ([], head2::tail2) -> head2 :: add1 [] tail2 | (head1::tail1, he

我需要用OCaml编写一个函数,在两个不同的递归中添加两个列表的元素:simple和tail。我做了一个简单的:

let rec add1 a b = 
match (a, b) with
      ([], []) -> []
    | (head1::tail1, []) -> head1 :: add1 tail1 []
    | ([], head2::tail2) -> head2 :: add1 [] tail2
    | (head1::tail1, head2::tail2) -> head1 + head2 :: add1 tail1 tail2
;;
它的工作原理如下:

add1 [1;2;3] [4;5;6;7];;
本申报表:

int list = [5; 7; 9; 7]
[1+4;2+5;3+6;0+7]
将0添加到7中,因为在第一个列表中该位置上没有元素

所以,我的问题是:


如何使用尾部递归实现它

尾部递归包含一个递归函数,该函数只执行对自身的调用,而无需任何其他操作

以下阶乘不是尾部递归的,因为最后一条语句不执行对事实的简单调用,而是需要乘法:

    let rec fact n = 
        if n = 0 then 1
        else n*(fact (n-1))
通过使用累加器,您可以使此函数尾部递归,最后一条语句执行对事实的调用,因此可以使用跳转而不是调用来编译:

    let rec fact n r =
        if n = 0 then r
        else fact (n-1) (r*n)
以及用法:

    fact 5 1

对于列表添加,如果两个列表至少具有相同的长度,则可以以相同的方式进行添加

尾部递归包含一个递归函数,该函数只执行对自身的调用,而无需任何其他操作

以下阶乘不是尾部递归的,因为最后一条语句不执行对事实的简单调用,而是需要乘法:

    let rec fact n = 
        if n = 0 then 1
        else n*(fact (n-1))
通过使用累加器,您可以使此函数尾部递归,最后一条语句执行对事实的调用,因此可以使用跳转而不是调用来编译:

    let rec fact n r =
        if n = 0 then r
        else fact (n-1) (r*n)
以及用法:

    fact 5 1

对于列表添加,如果两个列表至少具有相同的长度,则可以以相同的方式进行添加

使此尾部递归的方法是向后构建结果,并在递归中传递它,最后将其反转

let add1 a b =
  let rec loop acc = function
    | (xs, [])
    | ([], xs) -> List.rev_append acc xs
    | (x::xs, y::ys) -> loop ((x + y)::acc) (xs, ys)
  in
  loop [] (a, b)
注意:如果一个列表比另一个列表长,则不需要向每个元素添加0。尾巴已经是结果了。因此,我使用List.rev_append来反转累积值,并一次性追加剩余的尾部


注2:List.rev_append还可以追加空列表,因此不需要匹配([],[])。

使此尾部递归的方法是向后构建结果,并在递归中传递,最后将其反转

let add1 a b =
  let rec loop acc = function
    | (xs, [])
    | ([], xs) -> List.rev_append acc xs
    | (x::xs, y::ys) -> loop ((x + y)::acc) (xs, ys)
  in
  loop [] (a, b)
注意:如果一个列表比另一个列表长,则不需要向每个元素添加0。尾巴已经是结果了。因此,我使用List.rev_append来反转累积值,并一次性追加剩余的尾部


注2:List.rev_append还可以追加空列表,因此不需要匹配([],[])。

您是否必须处理两个列表长度不同的情况?是的,我需要,在我的第一个函数中,如果其中一个列表中没有类似位置的元素,我必须添加0。您必须处理两个列表长度不同的情况吗?是的,我需要,在我的第一个函数中,如果其中一个列表中没有类似位置的元素,我必须添加0