РЕДАКТИРОВАНИЕ: Изменены примеры, чтобы показать лень traversable.view
scala> def data(f : Int => Unit) = for(i <- 1 to 10) {
| println("Generating " + i)
| f(i)
| }
data: (f: (Int) => Unit)Unit
scala> def toTraversable[T]( func : (T => Unit) => Unit) = new Traversable[T] {
| def foreach[X]( f : T => X) = func(f(_) : Unit)
| }
toTraversable: [T](func: ((T) => Unit) => Unit)java.lang.Object with Traversable[T]
Метод toTraversable преобразует вашу функцию данных в коллекцию Traversable.Само по себе это ничего особенного, но вы можете преобразовать это в TraversableView, который ленив.Вот пример:
scala> toTraversable(data).view.take(3).sum
Generating 1
Generating 2
Generating 3
Generating 4
res1: Int = 6
Неудачная природа метода take заключается в том, что он должен пройти один раз после последнего сгенерированного значения, чтобы работать правильно, но он завершится рано.Приведенный выше код будет выглядеть так же без вызова ".view".Тем не менее, вот более убедительный пример:
scala> toTraversable(data).view.take(2).foreach(println)
Generating 1
1
Generating 2
2
Generating 3
Итак, в заключение, я считаю, что вы ищете коллекцию TraversableView, которая является наиболее простой для создания представления, создающего Traversable, а затем вызывающего «view» для него.,Если вам действительно нужен тип Stream, вот метод, который работает в 2.8.0.final и создаст «поток» без потоков:
scala> def dataToStream( data : (Int => Unit) => Unit) = {
| val x = new Traversable[Int] {
| def foreach[U](f : Int => U) = {
| data( f(_) : Unit)
| }
| }
| x.view.toList.toStream
| }
dataToStream: (data: ((Int) => Unit) => Unit)scala.collection.immutable.Stream[Int]
scala> dataToStream(data)
res8: scala.collection.immutable.Stream[Int] = Stream(0, ?)
К сожалению, этот метод будет повторятьсявесь пройденный прежде чем сделать поток.Это также означает, что все значения должны быть помещены в буфер.Единственная альтернатива - прибегать к потокам.
В качестве отступления: это было мотивирующей причиной, чтобы предпочесть Traversables в качестве прямого возврата от методов scalax.io.File: "lines", chars "и" bytes ".