Опишите вычисление - PullRequest
       62

Опишите вычисление

2 голосов
/ 22 сентября 2019

У меня есть следующий код, который я хотел бы знать, почему переменная number оценивается дважды:

import cats.effect.IO

import scala.util.Random

object Main {

  private val number: IO[Int] =
    IO(Random.between(3, 300))

  def main(args: Array[String]): Unit = {


    number
      .flatMap { e =>
        println(e);
        number
      }.flatMap { e =>
      println(e);
      IO.unit
    }.unsafeRunSync()
  }

}

программа печатает два разных числа, хотя номер является присваиванием.Я знаю здесь, я описываю вычисление, а не выполнение, и в конце вселенной я запускаю программу.

Вопрос в том, почему он печатает два разных числа?

Ответы [ 2 ]

4 голосов
/ 22 сентября 2019

Существует разница между

private val number: IO[Int] = IO(Random.nextInt())

и

private val number2: Int = Random.nextInt()

number - это значение, которое при оценке вычисляет случайное число.При многократной оценке это значение типа IO (иначе это вычисление) запускается несколько раз, что приводит к множеству различных случайных чисел.

Принимая во внимание, что number2 при оценке - только одно число.

Это очень похоже на различие между лямбда (val lambda = () => Random.nextInt()) и значением (val value = Random.nextInt()).

2 голосов
/ 22 сентября 2019

IO немного похож на следующий сценарий

final case class SuspendedComputation[T](f: () => T) {
  def run: T = f()
}

val v = SuspendedComputation(Random.nextInt)
v.run
v.run

, который выводит что-то вроде

v: SuspendedComputation[Int] = SuspendedComputation(<function>
res2: Int = -1062309211
res3: Int = 765640585

Обратите внимание, как SuspendedComputation внутренне сохраняет вычисления как () => Random.nextInt, а затемиспользует run метод для фактической оценки вычислений f.

Аналогично, IO.apply принимает аргумент по имени : => A и в конечном итоге создает Delay объект, который сохраняет необработанные вычисления в поле как () => A, а затем использует unsafeRunSync для фактической оценки вычислений.

...