List F#自定义附加函数

List F#自定义附加函数,list,function,recursion,design-patterns,f#,List,Function,Recursion,Design Patterns,F#,我有一个自定义函数将list2附加到list1 let append ls1 ls2 = let rec loop ls ls1 ls2 = match ls1, ls2 with | _, hd::tl -> loop (hd::ls) ls1 tl | hd::tl, _ -> loop (hd::ls) tl ls2 | _ -> ls loop [] ls1 ls2

我有一个自定义函数将list2附加到list1

let append ls1 ls2 =
    let rec loop ls ls1 ls2 =
        match ls1, ls2 with
        | _, hd::tl -> 
            loop (hd::ls) ls1 tl
        | hd::tl, _ -> loop (hd::ls) tl ls2
        | _ -> ls
    loop [] ls1 ls2
它很好用。但问题是当我调用函数时

let appended = append [1;2;3;4;5] [6;7;8;9;10]
它不是返回
[1;2;3;4;5;6;7;8;9;10]
而是返回

[5;4;3;2;1;10;9;8;7;6]

它会反转两个列表。

您需要反转列表。 解决方案的一种方法是思考
rev
函数的外观。 这是第一次尝试:

let rec rev lst =
    match lst with 
    | h::t -> (rev t)@[h]
    | [] -> []
此函数反转列表,但现在让我们执行另一个使用累加器的版本,这意味着在最后一行中不使用空列表,而是使用加法参数:

let rec rev lst acc =
    match lst with 
    | h::t -> rev t (h::acc)
    | [] -> acc
因此,现在我们必须将空列表作为参数传递:

rev [1..4] [];;
val-it:int-list=[4;3;2;1]

你可能想知道为什么我们需要这样一个函数,这个函数是,但这不是你的问题,你想附加两个列表。事实证明,这是90%的功能,你正在寻找

如果不是传递空列表,而是传递第二个列表:

rev [1..4] [5..8];;
val-it:int-list=[4;3;2;1;5;6;7;8]

非常接近,但是是的,第一个列表是反转的,好的,但是我们有一个函数可以反转列表,所以让我们反转第一个列表:

rev (rev [1..4] []) [5..8] ;;
val-it:int-list=[1;2;3;4;5;6;7;8]

很好,现在这个
rev
可能是我们的
循环
功能:

let append lst1 lst2 = 
    let rec rev lst acc =
        match lst with 
        | h::t -> rev t (h::acc)
        | [] -> acc
    rev (rev lst1 []) lst2

这与预期的一样,但请注意,我们只调用了两次参数化的
rev
函数。希望您了解函数式编程如何允许您组合函数以解决不同的问题。在本例中,我们将一个函数与它自身结合起来。

下面的代码是为我编写的

let rec append list1 list2 = 
   match list1, list2 with
    | hd::tl, _ -> hd::(append  tl list2)
    | _, hd::tl -> hd::(append list1 tl)
    | _ -> []
以下代码的输出为:

   let List1 = [1; 3; 5];
    let List2 = [7]
    printf "%A" append List1 List2


你的问题是什么?如果是关于错误的结果,那么请再想一想,记住
hd::tl
就像将
hd
附加到
tl
的头上,而不是附加到它的末尾。期望的结果是[1;2;3;4;5;6;7;8;9;10]这个问题与昨天的问题有什么不同?请看这里的答案。
[1; 3; 5; 7]