【问题标题】:Implementing tail recursion实现尾递归
【发布时间】:2019-04-07 07:11:39
【问题描述】:

我在 haskell 中编写了一个简单的函数,它是非尾递归的,它总结了列表中的值,其中:

nonTailRecursiveSum :: [Integer] -> Integer
nonTailRecursiveSum [] = 0 --base case
nonTailRecursiveSum (x:xs) = x + sum xs

但我现在要做的是实现相同的功能,但使用尾递归。据我所知,尾递归在最后一步执行递归调用,所以我尝试了类似的方法:

tailRecursiveSum :: [Integer] -> Integer
tailRecursiveSum [] = 0
tailRecursiveSum (x:xs) = aux_f(x) + tailRecursiveSum xs
.
.

但是我在中途迷路了,因为我不熟悉 Haskell 中的尾递归。任何人都可以帮助我继续代码的尾递归版本吗?

【问题讨论】:

  • sum (x:xs) = aux xs x 其中aux (x:xs) total = aux xs (x + total)
  • 为了使递归成为尾递归,您需要您的案例类似于tailRecursiveFunction something = tailRecursiveFunction somethingElse

标签: haskell recursion tail-recursion


【解决方案1】:

玩了一会儿,

sum (x:y:xs) = x + sum (y:xs)
             = x + (y + sum xs)
             = (x + y) + sum xs

g a b = a + sum b

sum (x:y:xs) = g x (y:xs)
             = x + g y xs
             = g (x+y) xs   -- !!!

最后一个是尾递归形式!因此,我们只需定义

sum xs = g 0 xs
  where
  g acc [] = ...
  g acc (x:xs) = g (acc + ...) ...

填空!

【讨论】:

  • 您可以立即从sum (x:xs) = g x xs 开始以避免0 + ...。 (这仅适用于 (+) 0 对于数字类型本质上是 id。)
  • 但是我必须单独处理[] 的情况。使用明确的0。这是不可避免的。
  • 最后一个(第一个代码块的)是尾递归形式是什么意思?
  • @DavidYoung 在g x (y:xs) = g (x+y) xs,对g 的调用是尾调用。
猜你喜欢
  • 1970-01-01
  • 2019-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-21
  • 1970-01-01
  • 2018-03-17
相关资源
最近更新 更多