描述一个计算
Describe a computation
我有以下代码,我想知道为什么变量 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()
}
}
该程序打印两个不同的数字,尽管该数字是一个赋值。我知道在这里,我描述的是计算而不是执行,在宇宙的尽头,我 运行 程序。
问题是,为什么打印出两个不同的数字?
有区别
private val number: IO[Int] = IO(Random.nextInt())
和
private val number2: Int = Random.nextInt()
number
是一个计算随机数的值。当多次评估时,此类型 IO
的值(又名此计算)是 运行 多次,导致多个不同的随机数。
而 number2
计算时只是一个数字。
这与lambda(val lambda = () => Random.nextInt()
)和值(val value = Random.nextInt()
)之间的区别非常相似。
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
accepts an argument by-name : => A
and eventually constructs Delay
对象将未评估的计算存储在字段中作为 () => A
,然后使用 unsafeRunSync
实际评估计算。
我有以下代码,我想知道为什么变量 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()
}
}
该程序打印两个不同的数字,尽管该数字是一个赋值。我知道在这里,我描述的是计算而不是执行,在宇宙的尽头,我 运行 程序。
问题是,为什么打印出两个不同的数字?
有区别
private val number: IO[Int] = IO(Random.nextInt())
和
private val number2: Int = Random.nextInt()
number
是一个计算随机数的值。当多次评估时,此类型 IO
的值(又名此计算)是 运行 多次,导致多个不同的随机数。
而 number2
计算时只是一个数字。
这与lambda(val lambda = () => Random.nextInt()
)和值(val value = Random.nextInt()
)之间的区别非常相似。
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
accepts an argument by-name : => A
and eventually constructs Delay
对象将未评估的计算存储在字段中作为 () => A
,然后使用 unsafeRunSync
实际评估计算。