私はKotlinシーケンス、特に以前の値の簡単な計算ではない複雑なものを試しています。Kotlinの無限シーケンスの再帰的定義
私が定義したい1つの例は、すべての素数のシーケンスです。
次の素数を定義する簡単な方法は、シーケンス内の前の素数のいずれかで割り切れない次の整数です。私はKotlinにこれを翻訳する問題を抱えてい
def primeStream(s: Stream[Int]): Stream[Int] = s.head #:: primeStream(s.tail filter(_ % s.head != 0))
val primes = primeStream(Stream.from(2))
// first 20 primes
primes.take(20).toList
:これはに変換することができScalaで
。スケーラでは、遅れて評価されるシーケンスを返す関数を渡すことができるので動作しますが、私はKotlinで同じことをすることはできません。 Kotlinで
私は
fun primes(seq: Sequence<Int>):Sequence<Int> = sequenceOf(seq.first()) + primes(seq.drop(1).filter {it % seq.first() != 0})
val primes = primes(sequence(2) {it + 1})
primes.take(20).toList()
を試みたが、機能がすぐに評価され、無限再帰につながるされているため、明らかに動作しません。
ニース。私がなぜ '' Sequence .plus(Sequence ) '](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.sequences/kotlin.-sequence/plus.html)が怠惰ではないのだろうか? 'lazyPlus'を実装しました... –
mfulton26
まあ、'シーケンス .plus(...) 'は怠惰ではありません。 :)結果の 'Sequence 'の項目は遅れて評価されますが、右オペランドの 'Sequence 'オブジェクトは熱心に評価されます。これは 'StackOverflowError'につながるのでここでは避ける必要があります。 –
hotkey
これは一般的なライブラリ関数として最適です。それは私のために速く働く。シーケンスをイテレータに変換し、primesFilterの実装で再び元に戻す必要性について説明できますか?あなたがそれをしなければちょっとしたもののように思えますが、怠惰な評価はうまくいかないと思います。これを必要としない可能性はありますか? –