문제

I'm new to scala and most functional languages and I'm currently trying to factor a number. i've written the code:

lazy val factors = for(int <- 2 until  math.ceil(math.sqrt(number)).toInt if number%int == 0) yield int

I was wondering If I declared the scala val as lazy will it not evaluate the entire for comprehension when I call factors.head?

도움이 되었습니까?

해결책

Your factors variable is lazy; the for comprehension isn't. When you access factors the first time, your for comprehension will be fully evaluated.

In Scala, for comprehension is merely a sugar for flatMap, map, and withFilter method calls. So if your backing data structure is strict (such as Range - which is what you are using), your for comprehension will also be strict. If the data structure is lazy (such as Stream), so will be for comprehension.

Observe the difference:

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, ?)

다른 팁

No. It is a completely different thing: lazy means that the value is computed the first time you access to it. If you want lazy computation for collections, you should use Stream or use a view. A Streamcan be built from a collection using view.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top