私はscalaとほとんどの関数型言語に不慣れで、現在数を因数分解しようとしています。私はコードを書いた:
lazy val factors = for(int <- 2 until math.ceil(math.sqrt(number)).toInt if number%int == 0) yield int
scala val を遅延として宣言した場合、呼び出したときに理解のために全体を評価しないのではないかと思っていましたfactors.head
か?
私はscalaとほとんどの関数型言語に不慣れで、現在数を因数分解しようとしています。私はコードを書いた:
lazy val factors = for(int <- 2 until math.ceil(math.sqrt(number)).toInt if number%int == 0) yield int
scala val を遅延として宣言した場合、呼び出したときに理解のために全体を評価しないのではないかと思っていましたfactors.head
か?
あなたのfactors
変数は怠惰です。for
理解はそうではありません。初めてアクセスfactors
するとき、あなたのfor
理解度は完全に評価されます。
Scala では、内包表記は、、およびメソッド呼び出しfor
の砂糖にすぎません。したがって、バッキング データ構造が厳密である場合 (使用している - など)、理解も厳密になります。データ構造が遅延している場合 ( など)、理解も遅延します。flatMap
map
withFilter
Range
for
Stream
for
違いを観察します。
scala> val number = 50
number: Int = 50
scala> lazy val factors = for(int <- 2 until math.ceil(math.sqrt(number)).toInt if number%int == 0) yield int
factors: scala.collection.immutable.IndexedSeq[Int] = <lazy>
scala> factors.head
res5: Int = 2
scala> factors
res6: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 5)
scala> lazy val factors = for(int <- Stream.range(2, math.ceil(math.sqrt(number)).toInt - 1) if number%int == 0) yield int
factors: scala.collection.immutable.Stream[Int] = <lazy>
scala> factors.head
res7: Int = 2
scala> factors
res8: scala.collection.immutable.Stream[Int] = Stream(2, ?)
いいえ、まったく別のことですlazy
。最初にアクセスしたときに値が計算されることを意味します。コレクションの遅延計算が必要な場合Stream
は、ビューを使用するか使用する必要があります。を使用してコレクションからStream
を構築できますview
。