【问题标题】:Why is the recursion idiom in Haskell "'n+1' and 'n'" and not "'n' and 'n-1'"?为什么 Haskell 中的递归习语是“'n+1' and 'n'”而不是“'n' and 'n-1'”?
【发布时间】:2011-02-16 14:26:08
【问题描述】:

我正在阅读 Graham Hutton 的 Haskell 书,在他的递归章节中,他经常在“n+1”上进行模式匹配,如下所示:

myReplicate1 0 _ = []
myReplicate1 (n+1) x = x : myReplicate1 n x

为什么是这样,而不是以下,哪个 (1) 在功能上看起来相同,(2) 在理解递归发生的事情方面更直观:

myReplicate2 0 _ = []
myReplicate2 n x = x : myReplicate2 (n-1) x

这里有什么我遗漏的吗?还是只是风格问题?

【问题讨论】:

    标签: haskell recursion idioms


    【解决方案1】:

    我认为它背后的想法是:我们可以像这样为自然数 (0, 1, ...) 定义一个类型:

    data Natural = Z -- zero
                 | S Natural -- one plus a number; the next number; the "successor"
    

    0 = Z1 = S Z 等等。这个系统被称为 Peano 算术,它几乎是数学中的一个标准,作为“数字”实际上是什么的(a 的起点)定义。您可以继续将Integers 定义为Naturals 的对(-ish),依此类推。

    当你这样做时,使用这样的模式匹配就变得很自然了:

    myReplicate1 Z _ = []
    myReplicate1 (S n) x = x : myReplicate1 n x
    

    我认为(这只是一个猜测)n+1 模式背后的想法是我刚才描述的机器版本。所以,n+1 被认为类似于模式S n。如果你这样想,n+1 模式看起来很自然。这也清楚地说明了为什么我们有 n >= 0 的附带条件。我们只能使用Natural 类型来表示n >= 0

    【讨论】:

      【解决方案2】:

      N+K 模式也有不同的严格含义。

      例如:

      f (n+1) = Just n
      g n = Just (n-1)
      

      f 对它的第一个参数是严格的,g 不是。这对于 n+k 模式没有什么特别之处,但适用于所有模式。

      【讨论】:

        【解决方案3】:

        第一个函数中的那些是 n+k 模式(应该避免!)。两个函数做同样的事情,除了 n+k 一个不匹配负数。但是,建议使用后一个,如果你故意不想要负数,可以采用,因为 n+k 模式被分解为removed anyways

        所以不,你什么都没有错过,这确实是风格问题,但我很少在野外看到 n+k 模式。

        【讨论】:

        • 换句话说,这是风格问题,第一种风格已被弃用。 :)
        • 它们实际上并不相同。 n+k 模式不会匹配负数。
        • 哎呀,没想到!谢谢,sepp,我编辑了我的答案!
        • 非常有趣 - 我想我错过了一些东西(n >= 0 位)。这是一种奇怪的魔法行为。我认为反对删除它的一个论点是“一些 Haskell 书籍使用它”很有趣 :)
        【解决方案4】:
        myReplicate n x = take n (repeat x)
        

        完成并完成。 :D

        【讨论】:

          【解决方案5】:

          n+k 模式仅在 n>=0 时匹配。因此,在您的 myReplicate1 中,n+1 模式将仅匹配正数,而负数 n 将导致非穷举模式异常。在 myReplicate2 中,负数 n 将创建一个无限列表。

          因此,换句话说,当您不希望模式匹配负数时,您可以使用 n+k 模式,但使用保护会更清晰。

          【讨论】:

            猜你喜欢
            • 2022-09-26
            • 2011-01-29
            • 2021-10-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-06-11
            • 2013-06-23
            • 1970-01-01
            相关资源
            最近更新 更多