[英]What is the advantage of Free monads over plain old traits with IO monads?
所以我一直在深入研究FP概念,我喜欢封装在IO monad中的纯度概念。 然后我读了这篇文章 ,并认为IO monad确实不像使用Free Monads那样解耦(?)。
所以我开始使用这些概念做我的东西,然后我意识到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将需要额外的样板(正如您在示例中所示)并且灵活性较低。 所以选择权是你的。
还有另一种方式 - 最终无标签。 这种方法试图平衡来自双方的专业人员,提供更少的供应商锁定,但仍然不像免费代数那样冗长。 值得一试。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.