我需要理解为什么这段代码有效:
myLength :: [a] -> Int
myLength [] = 0
myLength (_:xs) = 1 + myLength xs
如果我理解正确的递归,这个函数"重复"这段代码:
如果列表不为空,请转到下一步并执行任何操作
但是当列表为空时,它会在第一个列表中停止并且应该返回0
如果它使用像n这样的全局变量并执行类似的操作,我就能理解它:
myLength [] = n
myLength (_:xs) = (n+1) + myLength xs
它不起作用,但这个想法在那里,有一个价值' n'并在每次迭代中递增
答案 0 :(得分:2)
在你写的时候,它是递归。
让我们原则上看一下电话的执行情况:
myLength "abc"
匹配第二个重载,所以我们得到
1 + myLength "bc"
其中递归调用再次匹配第二个重载,因此等于
1 + 1 + myLength "c"
等于
1 + 1 + 1 + myLength ""
我们已达到基本情况
myLength [] = 0
所以递归终止,结果是
1 + 1 + 1 + 0
注意,当基本情况"返回0"这是特定应用函数的结果,而不是初始调用的结果。
这里的一个关键是函数的每个应用程序都会产生一个值。 也就是说,你不要进行下一步并做任何事情",你在尾部的长度上添加一个(这是一个值)。因此,您不需要某种全局状态(事实上,它只会使事情复杂化)。
另外,请注意,没有涉及赋值,函数定义了等式,因此左侧可以被右侧替换。