简体   繁体   English

递归在 Haskell 中如何工作? - 示例合并 function

[英]How does recursion work in Haskell? - Example merge function

if we look at the funtion definition of merge如果我们看一下合并的函数定义

merge (x:xs) (y:ys) | x <= y    = x:merge xs (y:ys)
                    | otherwise = y:merge (x:xs) ys

With the input [2,3] [4,1]输入 [2,3] [4,1]

the first step looks like this第一步看起来像这样

2<=4 => 2:merge [3] (1:[4])

Here my question lies: The first head element of the second list was 4 but since 2<=4 nothing was done with 4 so the 4 has to be still in the second list but the 4 needs to be the last element in the list now so 3 can be compared to the 1. I wonder how the compiler changes the second list: At first 4 was the head element but since it makes none sense to compare the 3 to the 4 again the indices has to be switched.我的问题在于:第二个列表的第一个头元素是 4,但是由于 2<=4 没有对 4 做任何事情,所以 4 必须仍在第二个列表中,但 4 现在必须是列表中的最后一个元素所以可以将 3 与 1 进行比较。我想知道编译器如何更改第二个列表:起初 4 是 head 元素,但由于再次将 3 与 4 进行比较没有意义,因此必须切换索引。

So the compiler just put the head element to the end of the list after the first comparison?那么编译器只是在第一次比较之后将头元素放在列表的末尾吗? Or what does the compiler do here?或者编译器在这里做什么?

I wonder how the compiler changes the second list.我想知道编译器如何更改第二个列表。

It does not.它不是。 If we call merge [2,3] [4,1] then the clause you describe will fire, with: x = 2 , y = 4 , xs = [3] and ys = [1] .如果我们调用merge [2,3] [4,1]那么您描述的子句将触发,其中: x = 2y = 4xs = [3]ys = [1] It will indeed check that 2 <= 4 , which holds, and then call merge with:它确实会检查2 <= 4是否成立,然后调用合并:

x : merge xs (y:ys)

so that means that if we use the variables we just assigned, we get:所以这意味着如果我们使用刚刚分配的变量,我们会得到:

2 : merge [3] (4:[1])

or less verbose:或更简洁:

2 : merge [3] [4,1]

I wonder how the compiler changes the second list: At first 4 was the head element but since it makes none sense to compare the 3 to the 4 again the indices has to be switched.我想知道编译器如何更改第二个列表:起初 4 是 head 元素,但由于再次比较 3 和 4 没有意义,因此必须切换索引。

Such merge function often has a precondition that the two lists it aims to merge, are sorted individually already.这种merge function 通常有一个前提条件,即它旨在合并的两个列表已经单独排序。 So normally merge [2,3] [4,1] will not be called with an algorithm like MergeSort , the two lists are first sorted, and then it is thus called with merge [2,3] [1,4] .所以通常不会用MergeSort之类的算法调用merge [2,3] [4,1] ,首先对两个列表进行排序,然后再使用merge [2,3] [1,4]调用它。

3 isn't compared to 1 until it has been compared to 4 as well;在将34进行比较之前,不会将 3 与1进行比较; merge preserves the relative order of each value within a single list. merge保留单个列表中每个值的相对顺序。

The recursion proceeds as follows:递归进行如下:

merge [2,3] [4,1] == 2 : merge [3] [4,1]  -- 2 < 4
                  == 2 : 3 : merge [] [4, 1] -- 3 < 4
                  == 2 : 3 : [4, 1] -- assuming merge [] ys == ys

Don't confuse merge with mergeSort , which uses merge as a subroutine.不要将merge使用merge作为子例程的mergeSort混淆。

mergeSort [] = []
mergeSort xs = merge (mergeSort first) (mergeSort second)
   where (first, second) = split xs
         split xs = ... -- some function to split a list roughly in half

The order-preserving behavior of merge is what makes mergeSort a stable sorting algorithm . mergeSort merge成为一种稳定的排序算法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM