gpt4 book ai didi

scala - 在 Scala 中的 Free Monad 中堆叠 Monadic 效果

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

我正在学习 Scala 中的 Free monad,并且我整理了一个简单的代数示例,我可以使用 cats 将其提升为 Free monad。

这是我的代数

sealed trait ConsultationOp[A]
object consultation {
case class Create(c: Consultation) extends ConsultationOp[Unit]
case class Get(s: ConsultationId) extends ConsultationOp[Option[Consultation]]
}

我可以像这样使用它

def app = for {
c <- consultation.Create(Consultation("123", "A consultation"))
_ <- consultation.Get(c._id)
} yield ()

def interpreters = ConsultationInterpreter or UserInterpreter
app.foldMap(interpreters)

ConsultationOpFree 的提升是隐式执行的。

(缺少很多细节,完整的工作实现在这里:https://github.com/gabro/free-api)

到目前为止一切顺利,但如果我需要提取 consultation.Get 返回的可选值怎么办?

首先想到的是 monad 转换器,即类似于

def app = for {
c <- consultation.Create(Consultation("123", "A consultation")).liftM[OptionT]
d <- OptionT(consultation.Get(c._id))
_ <- doSomethingAConsultation(d)
} yield ()

但是看起来很丑,而且感觉不太对劲。

使用免费单子(monad)时堆叠单子(monad)效果的最佳方式是什么(如果有)?

最佳答案

在这些情况下,我看到重复出现的常见方法是使用遍历,因此您可以按照以下方式更改代码:

import cats.syntax.traverse._
import cats.instances.option._

// ...

def app = for {
c <- consultation.Create(Consultation("123", "A consultation"))
d <- consultation.Get(c._id)
_ <- d.traverseU(doSomethingAConsultation(_))
} yield ()

恕我直言,这比 monad 变压器替代方案干净得多。请注意,您可能需要一些其他导入并稍微修改代码,我没有尝试过,但概念是:使用遍历。

关于scala - 在 Scala 中的 Free Monad 中堆叠 Monadic 效果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32765658/

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