[英]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 = 2
, y = 4
, xs = [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;在将
3
与4
进行比较之前,不会将 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.