2011-10-20 9 views
18

Secondo http://en.wikipedia.org/wiki/Fold_(higher-order_function), una piega destra può operare su liste infinite se l'elenco completo non deve essere valutato. Questo può essere visto in azione in Haskell:foldRight su infinita struttura pigra

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

Questo non sembra funzionare bene in scala per i flussi:

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

o iteratori:

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

c'è un pratico soluzione per ottenere una piega pigra proprio in Scala?

risposta

17

This article fa la stessa osservazione e suggerisce una soluzione pigra usando lo scalaz. Credito all'autore e Tony Morris.

+0

Grazie. Posso usare lo scalaz. Funziona per 'Stream'. Gli iteratori sembrano più insidiosi ... – huynhjl

+7

L'articolo non suggerisce affatto l'uso dello scalaz, ma dà una soluzione in scala pura che si dice sia stata ispirata dall'implementazione dello scalaz: 'def foldr [A, B] (combine: (A, = > B) => B, base: B) (xs: Stream [A]): ​​B = if (xs.isEmpty) base else combina (xs.head, foldr (combine, base) (xs.tail)) ' –