【发布时间】:2015-05-09 04:51:30
【问题描述】:
来自 Scala 背景,我非常习惯于使用尾递归来编写无法使用其他方法轻松表示的内容。假设我想计算列表的长度,但我不想使用折叠。我想以自然的尾递归方式来做。我是这样想的:
myLength :: [a] -> Int
myLength x = innerLength x 0
innerLength :: [a] -> Int -> Int -- Tail recursive inner call
innerLength [] _ = 0
innerLength (x:xs) n = innerLength xs n+1
这很好用。但是,innerLength 实际上是用于计算列表成员的尾递归内部调用并不是很可读,而且似乎 innerLength 的作用域是这样的,有人可以只使用 innerLength 而不是更好的 myLength。
有没有更好的方法来做到这一点?
【问题讨论】:
-
是的,在
myLength的定义中使用let或where子句。 -
innerLength xs n+1被解析为(innerLength xs n)+1,这是不是尾递归的。 -
@Franky 所说的,而且
innerLength [] _ = 0扔掉了累加器而不是返回它。应该是innerLength [] n = n。我也很想在递归情况下使用严格的应用程序,例如innerLength (_:xs) n = innerLength xs $! n+1 -
@Franky 感谢您指出这一点。对于使用 haskell 的我来说,这似乎一直是一个令人头疼的问题。
标签: haskell