私はスカラストリームで遊んでいます。 ここには、与えられた番号から始まるすべての整数のストリームがあります。
私はprintln
を追加して、from関数のすべての呼び出しをトレースしました。スカラストリームフィルタの動作
def from(n: Int): Stream[Int] = n #:: from({ println(n); n + 1 })
val nats = from(0) //> nats : Stream[Int] = Stream(0, ?)
nats.take(4).toList //> 0
//| 1
//| 2
//| 3
//| res0: List[Int] = List(0, 1, 2, 3, 4)
期待通り、これは私のscalaワークシートの出力です。それから私はすべての素数の流れを作りました。
def sieve(s: Stream[Int]): Stream[Int] = {
s.head #:: sieve(s.tail.filter({ println("---"); _ % s.head != 0 }))
} //> sieve: (s: Stream[Int])Stream[Int]
val primes = sieve(from(2))//> primes : Stream[Int] = Stream(2, ?)
primes.take(4).toList //> 2
//| ---
//| 3
//| 4
//| ---
//| 5
//| 6
//| ---
//| res1: List[Int] = List(2, 3, 5, 7)
ここで質問があります。私は、_
プレースホルダの代わりにx
パラメータを追加して、私の意見では少し変更するべきものを作った。驚くべきことに、出力はかなり異なっています:
def sieve(s: Stream[Int]): Stream[Int] = {
s.head #:: sieve(s.tail.filter(x => { println("---"); (x % s.head) != 0 }))
} //> sieve: (s: Stream[Int])Stream[Int]
val primes = sieve(from(2))//> primes : Stream[Int] = Stream(2, ?)
primes.take(4).toList //> 2
//| ---
//| 3
//| ---
//| 4
//| ---
//| ---
//| 5
//| ---
//| 6
//| ---
//| ---
//| ---
//| res1: List[Int] = List(2, 3, 5, 7)
私はこれらの繰り返しがすべてなぜ起こっているのか理解できません。 明示的なパラメータを使用すると何が問題になりますか?
説明のおかげで、私は違いが何かを得た。返された関数が同じ回数だけ何度もフィルタリングする必要があるのは明らかではありません。 – freedev
'{x => println(s" $ "s.head} --- $ x");と書くと、より良い結果が得られます。 x%s.head!= 0} '(そして、他のオプションと同様に、印刷された各行に対して、それが参照する' filter 'が表示されます) –
"返された関数がフィルタリングする回数が増えています... "というのは、返された関数ではなく、パラメータが匿名関数を使用してコレクション項目に適用されるためです。 _を使用したときにprintln。 –