やや直交、この現象がコルーチンを使用して達成することができます。コルーチンを可能にScalaのための少なくとも一つのライブラリがあり、あなたはここでそれを見つけることができます:代わりに、
import org.coroutines._
def sideEffectingFunction = coroutine {() =>
val limit = new scala.util.Random().nextInt(10)
val seq = new scala.util.Random
var counter = 0 // mutable state is preserved between coroutine invocations
while (counter < limit) {
counter += 1
yieldval(seq.nextInt)
}
}
defined function sideEffectingFunction
@ val cr = call(sideEffectingFunction())
cr: Coroutine.Frame[Int, Unit] = Coroutine.Frame<depth: 1, live: true>
@ cr.resume
res31: Boolean = true
@ cr.value
res32: Int = 57369026
@ cr.resume
res33: Boolean = true
@ cr.value
res34: Int = -1226825365
@ cr.resume
res35: Boolean = true
@ cr.value
res36: Int = 1304491970
@ cr.resume
res37: Boolean = false
@ cr.value
java.lang.RuntimeException: Coroutine has no value, because it did not yield.
scala.sys.package$.error(package.scala:27)
org.coroutines.Coroutine$Frame$mcI$sp.value$mcI$sp(Coroutine.scala:130)
cmd38$.<init>(Main.scala:196)
cmd38$.<clinit>(Main.scala:-1)
をまたは:ここ
http://storm-enroute.com/coroutines/はあなたが望む結果を得るために書くつもりコードの例です:
@ val cr = call(sideEffectingFunction())
cr: Coroutine.Frame[Int, Unit] = Coroutine.Frame<depth: 1, live: true>
@ cr.resume
res60: Boolean = true
@ val iter = Iterator.continually(cr.value).takeWhile(_ => cr.resume)
iter: Iterator[Int] = non-empty iterator
@ iter.foreach(println)
1595200585
995591197
-433181225
220387254
201795229
754208294
-363238006
T:前の回答の精神で
@ val cr = call(sideEffectingFunction())
cr: Coroutine.Frame[Int, Unit] = Coroutine.Frame<depth: 1, live: true>
@ while(cr.resume) println(cr.value)
-1888916682
1135466162
243385373
あるいは、コルーチンのアプローチの利点は、根底にある副作用関数の呼び出しの間に変更可能な状態を保つことができることです。すべてがコルーチン内の外側の世界からうまく隠されています。コルーチンは、構成してお互いに呼び出すこともできます。
もちろん、コルーチンは仕事を遂行するよりもはるかに強力なパワーを提供します。だから、これはちょうどこれを追加するのは難しいかもしれません。しかし、それは知っておくと便利なテクニックです。
優れた迅速な回答をいただきありがとうございます。 – satyagraha
最後のバージョンの.map(_。get)は、Scalaの最近のバージョンでは暗黙のTraversableOnce CBFとそれに関連するイテレータを導入する '.flatten'で置き換えられます。私はこれがまだ私の基準を満たしていると思います。 – satyagraha
あなたはそうです。私はそれを逃しました。なぜなら、Iteratorのscaladocには言及していないからです。 scaladocバグのようです: 'flatten'はエンリケメントクラス' TraversableOnce.FlattenOps'から来て、enrichementsはscaladoc(そして多くの人が扱うことになっています。私は自分の答えを更新しました。 –