私は私が完全に説明することができない結果でいくつかのテストを持っています。
最初のテストでは、4つの要素を含むリストでフィルター、マップ、およびリデュースを実行します。
{
val counter = new AtomicInteger(0)
val l = List(1, 2, 3, 4)
val filtered = l.filter{ i =>
counter.incrementAndGet()
true
}
val mapped = filtered.map{ i =>
counter.incrementAndGet()
i*2
}
val reduced = mapped.reduce{ (a, b) =>
counter.incrementAndGet()
a+b
}
println("counted " + counter.get + " and result is " + reduced)
assert(20 == reduced)
assert(11 == counter.get)
}
カウンターは、予想どおり11倍に増分されます。フィルタリング中に要素ごとに1回、マッピング中に要素ごとに1回、4つの要素を合計するために3回です。
ワイルドカードを使用すると、結果が変わります。
{
val counter = new AtomicInteger(0)
val l = List(1, 2, 3, 4)
val filtered = l.filter{
counter.incrementAndGet()
_ > 0
}
val mapped = filtered.map{
counter.incrementAndGet()
_*2
}
val reduced = mapped.reduce{ (a, b) =>
counter.incrementAndGet()
a+b
}
println("counted " + counter.get + " and result is " + reduced)
assert(20 == reduced)
assert(5 == counter.get)
}
リデュースでワイルドカードを使用する方法がわかりません(コードはコンパイルされません)が、現在、カウンターは5倍しかインクリメントされていません!!
それで、質問#1:なぜワイルドカードはカウンターが呼び出される回数を変更するのですか?それはどのように機能しますか?
次に、2番目の関連する質問です。ビューについての私の理解は、それらがモナディックメソッドに渡された関数を怠惰に実行するということでしたが、次のコードはそれを示していません。
{
val counter = new AtomicInteger(0)
val l = Seq(1, 2, 3, 4).view
val filtered = l.filter{
counter.incrementAndGet()
_ > 0
}
println("after filter: " + counter.get)
val mapped = filtered.map{
counter.incrementAndGet()
_*2
}
println("after map: " + counter.get)
val reduced = mapped.reduce{ (a, b) =>
counter.incrementAndGet()
a+b
}
println("after reduce: " + counter.get)
println("counted " + counter.get + " and result is " + reduced)
assert(20 == reduced)
assert(5 == counter.get)
}
出力は次のとおりです。
after filter: 1
after map: 2
after reduce: 5
counted 5 and result is 20
質問2:関数がすぐに実行されるのはなぜですか?
Scala2.10を使用しています