哈斯克尔。我很困惑这个代码片段是如何工作的

Posted

技术标签:

【中文标题】哈斯克尔。我很困惑这个代码片段是如何工作的【英文标题】:Haskell. Im confused how this code snippet works 【发布时间】:2020-07-26 13:53:22 【问题描述】:
magnitude :: Floating a => [a] -> a
magnitude = sqrt . mag
  where mag [] = 0
        mag (x:xs) = x^2 + mag xs

这应该对列表中的每个元素进行平方,然后取它们的总和,然后取平方根。很公平,但是当这个递归函数只将 x 添加到列表 xs 时,它是如何工作的呢?

【问题讨论】:

x 是列表的头部(第一个元素),它在尾部 xs 上使用递归。 【参考方案1】:

但是这个递归函数是如何工作的,当它只将x 添加到列表xs 中时?

x 是列表的头部(第一个元素),它在尾部xs 上使用递归。

例如对于列表[1,4,2,5],它通过以下方式获得总和:

mag [1,4,2,5]
    = 1 ^ 2 + mag [4,2,5]
    = 1 + mag [4,2,5]
    = 1 + (4 ^ 2 + mag [2,5])
    = 1 + (16 + mag [2,5])
    = 1 + (16 + (2 ^ 2 + mag [5]))
    = 1 + (16 + (4 + mag [5]))
    = 1 + (16 + (4 + (5 ^ 2 + mag [])))
    = 1 + (16 + (4 + (25 + mag [])))
    = 1 + (16 + (4 + (25 + 0)))
    = 1 + (16 + (4 + 25))
    = 1 + (16 + 29)
    = 1 + 45
    = 46

magnitude 定义为sqrt . mag,相当于\x -> sqrt (mag x)。这意味着我们首先计算xmag x 的平方和,然后计算该结果的平方根。

【讨论】:

【参考方案2】:

这应该对列表中的每个元素求平方,然后取它们的总和

这是由本地函数 mag 完成的。

mag [] = 0
mag (x:xs) = x^2 + mag xs

如果列表为空,则平方和为 0。如果为非空,则为第一个元素的平方加上列表其余部分的平方和。

然后取平方根。

这是由magnitude 完成的。它的定义等价于

magnitude xs = sqrt (mag xs)

但我们使用函数组合,.

magnitude xs = (sqrt.mag) xs

和无点样式(省略xs,因为它同时出现在左侧和右侧)

magnitude = sqrt.mag

【讨论】:

以上是关于哈斯克尔。我很困惑这个代码片段是如何工作的的主要内容,如果未能解决你的问题,请参考以下文章

哈斯克尔,再次。非法类型? [关闭]

使用scanl时空间泄漏在哪里? (哈斯克尔)

对这个带有 & 不带 = 的代码片段返回类型感到非常困惑

基于时间复杂度的这些片段真的很困惑

哪种最大选择算法更快? (哈斯克尔)[重复]

append() 在这个代码片段中是如何工作的?与特定变量混淆[重复]