foldRight在无限懒惰的结构上

huy*_*hjl 18 scala fold

根据http://en.wikipedia.org/wiki/Fold_(higher-order_function),如果不需要评估完整列表,右侧折叠可以在无限列表上运行.这可以在haskell中看到:

Prelude> take 5 (foldr (:) [] [1 ..])
[1,2,3,4,5]
Run Code Online (Sandbox Code Playgroud)

这似乎在流的scala中不能很好地工作:

Stream.from(1).foldRight(Stream.empty[Int])( (i, s) => i #:: s).take(5)
// StackOverflowError
Run Code Online (Sandbox Code Playgroud)

或者在迭代器上:

Iterator.from(1).foldRight(Iterator.empty: Iterator[Int]){ (i, it) => 
  Iterator.single(i) ++ it
}.take(5)
// OutOfMemoryError: Java heap space
Run Code Online (Sandbox Code Playgroud)

有没有一个实用的解决方案来实现Scala中的懒惰折叠?

Tim*_*Tim 17

本文做了相同的观察,并建议使用scalaz的懒惰解决方案.感谢作者和Tony Morris.

  • 文章根本没有建议使用scalaz,但是给出了纯scala的解决方案,它说灵感来自scalaz的实现:`def foldr [A,B](组合:(A,=> B)=> B,base :B)(xs:Stream [A]):B = if(xs.isEmpty)base else combine(xs.head,foldr(combine,base)(xs.tail))` (7认同)