Ленивый для оценки понимания в scala

Я новичок в scala и большинстве функциональных языков, и сейчас я пытаюсь вычислить число. я написал код:

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

Мне было интересно, если бы я объявил scala val ленивым, не будет ли он оценивать все для понимания, когда я вызываю factors.head?




Ответы (2)


Ваша переменная 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, ?)
person missingfaktor    schedule 12.06.2012

Нет. Это совсем другое: lazy означает, что значение вычисляется при первом доступе к нему. Если вам нужны ленивые вычисления для коллекций, вы должны использовать Stream или используйте представление. Streamможно построить из коллекции с помощью view.

person Nicolas    schedule 12.06.2012