实施折叠与理解

时间:2016-09-21 13:55:55

标签: scala

如何在Scala中将fold实现为for-comprehension?我看到唯一的方法是使用一些递归调用?这是一个失败的尝试,不知道如何做到这一点?将fold作为for-comprehension

实施的最佳方式是什么?
  val nums = List(1,2,3)                         
  nums.fold(0)(_+_)                              
  def recFold(acc: Int = 0): Int = {
    (for {
        a <- nums
        b = recFold(a + acc)
    } yield b).head
  }                                               
    recFold(0) //Stack overflow

2 个答案:

答案 0 :(得分:2)

如果你真的想使用for,你不需要递归,但你需要一个可变变量:

val nums = List(1,2,3)

def recFold(zero: Int)(op: (Int, Int) => Int): Int = {
  var result: Int = zero
  for { a <- nums } result = op(result, a)
  result
}

recFold(0)(_ + _) // 6

这与foldLeft中实际TraversableOnce的实施方式非常相似:

def foldLeft[B](z: B)(op: (B, A) => B): B = {
  var result = z
  this foreach (x => result = op(result, x))
  result
}

答案 1 :(得分:0)

折叠可以从右到左,从左到右实现。无需使用for加递归。递归就足够了。

  def foldRight[A, B](as: List[A], z: B)(f: (A, B) => B): B = {
    as match {
      case Nil => z
      case x :: xs => f(x, foldRight(xs, z)(f))
    }
  }

  @annotation.tailrec
  def foldLeft[A, B](as: List[A], z: B)(f: (A, B) => B): B = {
    as match {
      case Nil => z
      case x :: xs => foldLeft(xs, f(x, z))(f)
    }
  }
相关问题