2016-09-21 108 views
1

在斯卡拉如何將fold作爲for-comprehension實現?我看到唯一的方法是使用一些遞歸調用?這是一個失敗的嘗試,不知道如何做到這一點?什麼是執行foldfor-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 
+0

我對scala沒有太豐富的經驗,但我沒有看到從你的遞歸調用返回的基本情況? –

+0

使用'頭部'是不安全的 – cchantep

回答

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 

這是非常相似,如何foldLeftTraversableOnce實際執行:

def foldLeft[B](z: B)(op: (B, A) => B): B = { 
    var result = z 
    this foreach (x => result = op(result, x)) 
    result 
} 
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) 
    } 
    } 
+0

我只是有興趣,如果有一些超級聰明的方式來使用一個似乎總是似乎在FP ... – user3139545