ZIO:如何只计算一次? [英] ZIO : How to compute only once?

查看:99
本文介绍了ZIO:如何只计算一次?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

在我的build.sbt中:

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

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

No matter what I tried, my results are always being computed each time I need them:

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

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

    println(r)

对于此示例,日志如下所示:

For this example, the log look like :

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
    }

首先,我在想也许执行了管道,但没有重新计算值,但我也没有用.

first and I was thinking that maybe the pipeline is executed but not the value recomputed but I does not work either.

我希望能够异步计算我的值并能够重用它们. 我看着如何使Scalaz ZIO变得懒惰? ,但这对我也不起作用.

I would like to be able to compute asynchronously my values and be able to reuse them. I looked at How do I make a Scalaz ZIO lazy? but it does not work for me either.

推荐答案

计算结果是否有副作用?如果不是这样,您可以只使用常规的旧惰性val,也许可以将其放入ZIO.

Does computing the results have side effects? If it doesn't you can just use a regular old lazy val, perhaps lifted into ZIO.

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

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

If it does have side effects, you can't really cache the results because that wouldn't be referentially transparent, which is the whole point of ZIO. What you'll probably have to do is flatMap on your compute Task and write the rest of your program which needs the result of that computation inside that call to flatMap, threading the result value as a parameter through your function calls where necessary.

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

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

这篇关于ZIO:如何只计算一次?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆