【问题标题】:Tail Recursion and Side effect尾递归和副作用
【发布时间】:2012-10-02 02:41:24
【问题描述】:

我实际上正在学习 scala,我有一个关于尾递归的问题。这是 scala 中带有尾递归的阶乘示例:

    def factorial(n: Int): Int = {

    @tailrec
    def loop(acc: Int, n: Int): Int = {
      if (n == 0) acc
      else loop(n * acc, n - 1)
    }
    loop(1, n)
  }              

我的问题是更新参数,acc 就像我们在函数loop 中所做的那样可以认为是副作用吗?由于在 FP 中,我们希望防止或减少副作用的风险。

也许我弄错了,但有人可以向我解释这个概念。

感谢您的帮助

【问题讨论】:

  • 不,它没有。纯函数根据定义不包含副作用,并且循环是纯函数(它仅取决于传入的参数)。
  • 我认为应该将@tailrec 移动到您的loop 函数中。函数loop 是递归的,而factorial 不是——它从不调用自己,它只调用loop
  • 谢谢彼得,你完全正确!!!

标签: scala functional-programming tail-recursion


【解决方案1】:

您实际上并没有在此处更改任何参数的值(因为根据定义,它们是 vals,即使您愿意,也不能这样做)。

您正在返回一个新值,该值是根据传入的参数(并且只有那些)计算得出的。正如@om-nom-nom 在他的评论中指出的那样,这是纯函数的定义。

【讨论】:

  • 也就是说,值得注意的是,纯函数式程序使用这种尾递归传递来模拟状态并不罕见。尤其是 Erlang 以永远运行的进程而闻名,这些进程不断地递归地将状态尾传递给自己,永远
  • 与其说是模拟状态,不如说是明确地说明状态的概念隐含的含义。如果一个(纯)函数依赖于已经执行的计算,那么这些计算肯定会产生一些值,这些值通过它的参数传递给函数。
猜你喜欢
  • 2016-03-21
  • 2011-11-14
  • 2015-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-17
  • 1970-01-01
相关资源
最近更新 更多