gpt4 book ai didi

scala - 与 IO monads 的普通旧特征相比,Free monads 有什么优势?

转载 作者:行者123 更新时间:2023-12-02 04:33:01 29 4
gpt4 key购买 nike

所以我对 FP 概念越来越深入,我喜欢 IO monad 中包含的纯度概念。然后我读了this ,并认为 IO monad 确实不像使用 Free Monad 那样解耦(?)。

所以我开始使用这些概念做我的事情,然后我意识到 traits 实现了将结构与执行分开的相同目的。更糟糕的是,使用免费的 monad 有很多限制,比如错误处理和将上下文边界和隐式参数传递给解释器/实现。

所以我的问题是:使用它们有什么好处?如何解决我刚才提到的问题(隐式参数和错误处理)? Free Monands 的使用仅限于学术领域,还是可以在工业界使用?

编辑:一个解释我疑惑的例子

  import cats.free.Free._
import cats.free.Free
import cats.{Id, ~>}

import scala.concurrent.Future

sealed trait AppOpF[+A]

case class Put[T](key: String, value: T) extends AppOpF[Unit]

case class Delete(key: String) extends AppOpF[Unit]
//I purposely had this extend AppOpF[T] and not AppOpF[Option[T]]
case class Get[T](key: String) extends AppOpF[T]

object AppOpF {
type AppOp[T] = Free[AppOpF, T]

def put[T](key: String, value: T): AppOp[Unit] = liftF[AppOpF, Unit](Put(key, value))

def delete(key: String): AppOp[Unit] = liftF[AppOpF, Unit](Delete(key))

def get[T](key: String): AppOp[T] = liftF[AppOpF, T](Get(key))

def update[T](key: String, func: T => T): Free[AppOpF, Unit] = for {
//How do I manage the error here, if there's nothing saved in that key?
t <- get[T](key)
_ <- put[T](key, func(t))
} yield ()


}

object AppOpInterpreter1 extends (AppOpF ~> Id) {
override def apply[A](fa: AppOpF[A]) = {
fa match {
case Put(key,value)=>
???
case Delete(key)=>
???
case Get(key) =>
???
}
}
}
//Another implementation, with a different context monad, ok, that's good
object AppOpInterpreter2 extends (AppOpF ~> Future) {
override def apply[A](fa: AppOpF[A]) = {
fa match {
case a@Put(key,value)=>
//What if I need a Json Writes or a ClassTag here??
???
case a@Delete(key)=>
???
case a@Get(key) =>
???
}
}
}

最佳答案

IO monad 的自由代数服务于相同的目的 - 将程序构建为纯数据结构。如果将 Free 与 IO 的一些具体实现进行比较,IO 可能会获胜。它将具有更多功能和专业特性,可帮助您快速行动并快速开发您的程序。但这也意味着您将在一种 IO 实现上锁定主要供应商。无论您选择哪个 IO,它都将是一个具体的 IO 库,可能存在性能问题、错误或支持问题——谁知道呢。由于程序和实现之间的这种紧密耦合,将您的程序从一个供应商更改为另一个供应商将花费您很多。

另一方面,自由代数允许您在不谈论程序实现的情况下表达您的程序。它以一种您可以轻松测试和独立更改它们的方式将您的需求与实现分开。作为另一个好处,Free 允许您根本不使用 IO。您可以在其中包装标准 Futures、java 的标准 CompletableFuture 或任何其他第三方并发原语,您的程序仍然是纯净的。为此,Free 将需要额外的样板(就像您在示例中展示的那样)并且灵 active 较低。所以选择是你的。

还有另一种方式 - final 无标记。这种方法试图平衡双方的专业人士,提供更少的供应商锁定,并且仍然不像免费代数那样冗长。值得一试。

关于scala - 与 IO monads 的普通旧特征相比,Free monads 有什么优势?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46766192/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com