Haskell无尾递归
我想知道这是否表示尾部递归。如果不是,我该怎么做Haskell无尾递归,haskell,Haskell,我想知道这是否表示尾部递归。如果不是,我该怎么做 countP :: [a] -> (a->Bool) -> Int countP [] _ = 0 countP (x:xs) p = countP_aux (x:xs) p 0 countP_aux [] _ _ = 0 countP_aux (x:xs) p acumul |p x==True = (countP_aux xs p (acumul))+1
countP :: [a] -> (a->Bool) -> Int
countP [] _ = 0
countP (x:xs) p = countP_aux (x:xs) p 0
countP_aux [] _ _ = 0
countP_aux (x:xs) p acumul
|p x==True = (countP_aux xs p (acumul))+1
|otherwise = (countP_aux xs p (acumul))
countP [1,2,3] (>0)
3
(72 reductions, 95 cells)
此练习显示列表中有多少值通过p条件验证。
谢谢这不是尾部递归,因为
(countP_aux xs p (acumul))+1
尾部调用应该返回递归调用的结果,而不是使用递归调用的结果进行计算
您可以使用累加器将非尾部递归函数转换为尾部递归函数,在累加器中执行附加工作,即
假设你有一个简单的计数功能
f a
| a < 1 = 0
| otherwise = f (a-1) + 1
您可以将其设置为尾部递归,如下所示:
f' acc a =
| a < 1 = acc
| otherwise = f' (acc + 1) (a-1)
f = f' 0
这不是尾部递归,因为
(countP_aux xs p (acumul))+1
尾部调用应该返回递归调用的结果,而不是使用递归调用的结果进行计算
您可以使用累加器将非尾部递归函数转换为尾部递归函数,在累加器中执行附加工作,即
假设你有一个简单的计数功能
f a
| a < 1 = 0
| otherwise = f (a-1) + 1
您可以将其设置为尾部递归,如下所示:
f' acc a =
| a < 1 = acc
| otherwise = f' (acc + 1) (a-1)
f = f' 0
我遇到了双重否定的问题-如果它不是一个非尾部递归意味着什么?顺便说一句,我认为countP[]f应该总是返回0。你的代码失败了。我想知道它是否代表尾部递归。Post Edited如果它是尾部递归为什么重要?尾部递归比非尾部递归有更好的性能recursion@tomss不存在惰性评估。尾部递归在严格的语言中更快,但Haskell是非严格的。你应该读一读,我遇到了双重否定的问题——如果它不是无尾递归,意味着什么?顺便说一句,我认为countP[]f应该总是返回0。你的代码失败了。我想知道它是否代表尾部递归。Post Edited如果它是尾部递归为什么重要?尾部递归比非尾部递归有更好的性能recursion@tomss不存在惰性评估。尾部递归在严格的语言中更快,但Haskell是非严格的。你应该读书,我怎么做?谢谢。重构到f'acc a然后让f=f'0可能会很好,对累加器进行排序也可能会很好……因为这样你就不会建立一大堆未评估的thunks。ghc可能自己就能解决这个问题,不是吗?给定的东西是尾部递归的,懒惰累加器的问题是其他的。我该怎么做呢?谢谢。重构到f'acc a然后让f=f'0可能会很好,对累加器进行排序也可能会很好……因为这样你就不会建立一大堆未评估的thunks。ghc可能自己就能解决这个问题,不是吗?给定的东西是尾部递归的,惰性累加器的问题是其他的。