我正在玩斯卡拉流。 這裏是從給定數字開始的所有整數流。
我添加了一個println
來跟蹤函數的每個調用。斯卡拉流過濾器行爲
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}'(對於其他選項也是類似的,然後你會看到每一行打印的行是「過濾」的, –
「......不清楚爲什麼返回的函數有要過濾更多次......「,這不是因爲它是返回的函數,而是因爲過濾器使用參數中的匿名函數應用於集合項目中。匿名函數(x => ...)不包含println當你使用_。 –