2011-10-20 11 views
18

Zgodnie z http://en.wikipedia.org/wiki/Fold_(higher-order_function), prawy zakład może działać na nieskończonych listach, jeśli pełna lista nie musi być oceniona. Można to zobaczyć w akcji w Haskell:foldRight na nieskończonej leniwej strukturze

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

ten nie wydaje się działać dobrze w Scala dla strumieni:

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

lub na iteratorów:

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

Czy istnieje praktyczna rozwiązanie, aby osiągnąć leniwy skład w Scali?

Odpowiedz

17

This article robi tę samą obserwację i sugeruje leniwe rozwiązanie za pomocą skalaza. Podziękowania dla autora i Tony'ego Morrisa.

+0

Dziękuję. Mogę użyć skalaza. Działa dla 'Stream'. Iteratory wydają się być trudniejsze ... – huynhjl

+7

Artykuł nie sugeruje użycia skalasem, ale daje rozwiązanie w czystej scali, która jest zainspirowana implementacją scalaz: 'def foldr [A, B] (Combine: (A, = > B) => B, podstawa: B) (xs: Strumień [A]): ​​B = jeśli (xs.isEmpty) baza jeszcze się łączy (xs.head, foldr (Combine, base) (Xs.tail)) ' –

Powiązane problemy