在Haskell中解释这个'Merge'函数

时间:2013-12-10 15:58:06

标签: sorting haskell mergesort

我正在学习Haskell,我无法理解这个功能。我正在实施mergesort。我实现了mergesort递归函数,但我不明白这个'merge'函数在做什么。我理解命令式语言中的合并排序,但我不理解这里的语法。

merge []         ys                   = ys
merge xs         []                   = xs
merge xs@(x:xt) ys@(y:yt) | x <= y    = x : merge xt ys
                          | otherwise = y : merge xs yt

3 个答案:

答案 0 :(得分:12)

merge []         ys                   = ys

如果第一个参数为空,则给出第二个参数。

merge xs         []                   = xs

如果第二个参数为空,则给出第一个参数。

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

如果x小于或等于y,请将(添加到前面)x合并到xs的其余部分(xtys。否则y较小,因此将xs与ys的其余部分(yt)合并后的结果。

xs@(x:xt)是使用“占位符”的参数解构。结果是xs将引用整个第一个参数,而x是头部,xt是尾部。

由于合并是递归定义的,它将继续使用xs和ys中的元素,直到至少有一个为空,然后简单地返回它。

条形图(|)表示"guards",它允许您以简洁明了的方式定义条件。

答案 1 :(得分:3)

让我们逐行打破这个:

  1. merge [] ys = ys

    此行模式与第一个列表匹配。如果第一个列表是空列表(即[]),则返回第二个列表。

  2. merge xs [] = xs

    与之前相同,只是反对列表角色。

  3. merge xs@(x:xt) ys@(y:yt)

    仅当list元素非空时,类似(x:xt)的模式匹配才匹配。如果匹配x设置为第一个元素,则xt设置为列表的其余部分。请记住:是列表构造函数运算符(即1 : [2, 3] == [1, 2, 3])。 xs@...前缀表示整个列表设置为xs。如果您需要同时参考整个列表及其头部和尾部,这将非常有用。

答案 2 :(得分:2)

函数模式匹配它的两个参数。让我们看看每个条款:

merge []         ys                   = ys

因此,合并空列表和另一个列表y会导致ys。

merge xs         []                   = xs

这就像第一个子句,反过来说:合并列表xs和空列表给出了xs。

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

这是递归子句。这里函数模式匹配它的两个参数,因此:

  • xs是第一个列表,并且被解构(通过as-pattern)到头部x和尾部xt
  • ys是第二个列表,它被解构为头部y,它的尾部为yt

现在,如果第一个列表的头部小于或等于第二个列表的头部(第一个保护),则结果只是第一个列表y的头部,后面是合并的结果第一个列表的尾部(这是xt)和第二个列表ys。如果y小于x,我们会相反。