来自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。
有更好的方法吗?
答案 0 :(得分:2)
是的,您可以使用let
:
myLength :: [a] -> Int
myLength x =
let innerLength :: [a] -> Int -> Int -- Tail recursive inner call
innerLength [] n = n
innerLength (x:xs) n = innerLength xs (n+1)
in innerLength x 0
或where
:
myLength :: [a] -> Int
myLength x = innerLength x 0
where innerLength :: [a] -> Int -> Int -- Tail recursive inner call
innerLength [] n = n
innerLength (x:xs) n = innerLength xs (n+1)
请参阅here了解两者之间的差异。