2011-10-20 10 views
18

De acuerdo con http://en.wikipedia.org/wiki/Fold_(higher-order_function), un doblez a la derecha puede operar en listas infinitas si la lista completa no tiene que ser evaluada. Esto se puede ver en acción en Haskell:foldRight en infinita estructura perezosa

Prelude> take 5 (foldr (:) [] [1 ..]) 
[1,2,3,4,5] 

Esto no parece funcionar bien en Scala para los flujos:

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

o en iteradores:

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

¿Existe una práctica solución para lograr un doblez lento en Scala?

Respuesta

17

This article hace la misma observación, y sugiere una solución perezosa usando scalaz. Gracias al autor y Tony Morris.

+0

Gracias. Puedo usar Scalaz. Funciona para 'Stream'. Los iteradores parecen más complicados ... – huynhjl

+7

El artículo no sugiere usar Scalaz en absoluto, pero ofrece una solución en scala pura que dice que fue inspirada por la implementación de scalaz: 'def foldr [A, B] (combine: (A, = > B) => B, base: B) (xs: Stream [A]): ​​B = if (xs.isEmpty) base else combine (xs.head, foldr (combine, base) (xs.tail)) ' –