【问题标题】:ZIO : How to compute only once?ZIO:如何只计算一次?
【发布时间】:2019-11-18 12:14:22
【问题描述】:

我正在使用 ZIO:https://github.com/zio/zio

在我的build.sbt:

"dev.zio" %% "zio" % "1.0.0-RC9"

无论我尝试了什么,我的结果总是在每次需要时被计算出来:

val t = Task {
  println(s"Compute")
  12
}

    val r = unsafeRun(for {
      tt1 <- t
      tt2 <- t
    } yield {
      tt1 + tt2
    })

    println(r)

对于这个例子,日志看起来像:

Compute
Compute
24

我试过Promise


    val p = for {
      p <- Promise.make[Nothing, Int]
      _ <- p.succeed {
        println(s"Compute - P")
        48
      }
      r <- p.await
    } yield {
      r
    }

    val r = unsafeRun(for {
      tt1 <- p
      tt2 <- p
    } yield {
      tt1 + tt2
    })

我也遇到了同样的问题:

Compute - P
Compute - P
96

我试过了

    val p = for {
      p <- Promise.make[Nothing, Int]
      _ <- p.succeed(48)
      r <- p.await
    } yield {
      println(s"Compute - P")
      r
    }

首先,我在想也许管道已执行,但没有重新计算值,但我也不工作。

我希望能够异步计算我的值并能够重用它们。 我查看了How do I make a Scalaz ZIO lazy?,但它对我也不起作用。

【问题讨论】:

  • 我不知道 Zio 是否有这样的能力(可能出于性能原因)。但是,重要的是您知道这样做会破坏 引用透明性 原则,从某种意义上说,这是使用任何类型的 IO Monad。如果您不关心这一点,而只想要异步计算,那么只需使用Future
  • Monix Taskmemoize 方法,也许改用它?

标签: scala functional-programming zio


【解决方案1】:

计算结果有副作用吗?如果不是,您可以使用常规的旧惰性 val,也许提升到 ZIO

lazy val results = computeResults()
val resultsIO = ZIO.succeedLazy(results)

如果它确实有副作用,你就不能真正缓存结果,因为这不会是引用透明的,这就是ZIO 的重点。 您可能需要做的是在您的计算 Task 上进行 flatMap 并编写程序的其余部分,该程序需要在对 flatMap 的调用中的计算结果,通过线程将 result 值作为参数必要时调用你的函数。

val compute = Task {
  println(s"Compute")
  12
}

compute.flatMap { result =>
  // the rest of your program
}

【讨论】:

    【解决方案2】:

    ZIO 有memoize,它应该可以满足您的需求。我现在没有办法测试它,但它应该像这样工作:

    for {
      memoized <- t.memoize
      tt1 <- memoized
      tt2 <- memoized
    } yield tt1 + tt2
    

    请注意,除非您的真实代码的第二行和第三行有一些可能导致 Task 永远不会被调用或只被调用一次的分支,否则这会产生与更简单的代码相同的答案和副作用:

    t flatMap {tt => tt + tt}
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-09
    • 1970-01-01
    • 1970-01-01
    • 2015-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多