сделать. Помимо прочего нагуглилось вот это https://stackoverflow.com/questions/3797699/generator-block-to-iterator-stream-conversion
В общем, топовый ответ оттуда:
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]
Использование:
scala> toTraversable(data).view.take(3).sum
Generating 1
Generating 2
Generating 3
Generating 4
res1: Int = 6
Если в дебагере смотреть, Traversable генерируется до конца (так полагаю watcher'ы высчитываются и побуждают эту генерацию), но потом все таки выполняется take(3), но не как я бы ожидала. Там магия какая-то: внутри data, после выполнения f(i) мы перескакиваем обратно на foreach в traversable, а как бы цикл for(i <- 1 to 10), который внутри data, игнорируем. Я увидела breaks в traversable trait'е, но не осилила где они используются и как это работает. Anyone knows?
def invoke { try{ def f = (i:Int) => { if (enough) throw hitriiexception } data(f) }catch { case x:hitriiexception => } } типа того. брейк, ретурн - также через эксепшены работают - сахарок
Обсуждают сегодня