【问题标题】:What is the benefit of effect system (e.g. ZIO)?效果系统(例如 ZIO)有什么好处?
【发布时间】:2022-01-22 10:06:34
【问题描述】:

我很难理解什么是价值效应系统,例如 ZIO 或 Cats Effect。

  • 它不会使代码可读,例如:
val wrappedB = for {
   a <- getA()  // : ZIO[R, E, A]
   b <- getB(a) // : ZIO[R, E, B]
} yield b

对我来说并不比以下内容更具可读性:

val a = getA()  // : A
val b = getB(a) // : B

我什至可以争辩说,后者更直接,因为调用函数会执行它,而不仅仅是创建效果或执行管道。

  • 延迟执行听起来并不令人信服,因为到目前为止我遇到的所有示例都只是立即执行管道。恕我直言,可以通过更简单的方式实现并行或多次执行效果,例如C# 有 Parallel.ForEach
  • 可组合性。可以在不使用效果的情况下组合函数,例如通过简单的构图。
  • 纯函数方法。最后将执行纯 instructions,所以它似乎只是假装 DB 访问是纯的。推理无济于事,因为虽然指令的构造是纯粹的,但执行它们却不是。

我可能遗漏了一些东西,或者只是淡化了上述好处,或者在某些情况下(例如复杂领域),好处可能更大。 使用效果系统的最大卖点是什么?

【问题讨论】:

标签: scala functional-programming


【解决方案1】:

因为它可以很容易地处理副作用。从你的例子:

a <- getA()  // ZIO[R, E, A] (doesn't have to be ZIO btw)

val a = getA(): A

第一个 getA 说明效果和返回错误的可能性,一个副作用。这就像从某个数据库中获取一个 A,其中所述 A 可能不存在,或者您没有访问它的权限。第二个 getA 就像一个简单的 def getA = "A"
我们如何将这些方法组合在一起?如果有人抛出错误怎么办?我们应该继续使用下一个方法还是直接退出?如果有人阻塞了你的线程怎么办?

希望这能解决您关于可组合性的第二点。快速解决剩下的问题:

  • 延迟执行。这可能有两个原因。首先是您实际上不想意外开始执行。或者只是因为你写了它,它马上就开始了。这打破了酷家伙所说的引用透明度。第二个是并发执行需要一个线程池或执行上下文。通常我们希望有一个集中的地方,我们可以为整个应用程序微调它。在构建库时,我们无法自己提供。提供它的是用户。事实上,我们也可以推迟效果。您所做的只是定义效果应该如何表现以及用户可以使用 ZIO、Monix 等,这完全取决于他们。
  • 纯度。从技术上讲,将流程包装在纯效果中并不一定意味着底层流程实际使用它。只有实现才知道它是否真的被使用过。我们能做的就是提升它以使其与构图兼容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-16
    • 1970-01-01
    • 1970-01-01
    • 2016-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多