我正在學習Scala中的免費monad,並且我已經組合了一個簡單的代數示例,可以使用貓將其提升爲免費monad。在Scala中堆疊免費Monad中的單點特效
這裏是我的代數
sealed trait ConsultationOp[A]
object consultation {
case class Create(c: Consultation) extends ConsultationOp[Unit]
case class Get(s: ConsultationId) extends ConsultationOp[Option[Consultation]]
}
而且我能夠使用它等,其中隱式執行從ConsultationOp
到Free
提升
def app = for {
c <- consultation.Create(Consultation("123", "A consultation"))
_ <- consultation.Get(c._id)
} yield()
def interpreters = ConsultationInterpreter or UserInterpreter
app.foldMap(interpreters)
。
(還有很多細節丟失,全面執行工作是在這裏:https://github.com/gabro/free-api)
到目前爲止好,但如果我需要提取由consultation.Get
返回的可選值什麼。
,想到的第一件事是一個單子轉換,即像
def app = for {
c <- consultation.Create(Consultation("123", "A consultation")).liftM[OptionT]
d <- OptionT(consultation.Get(c._id))
_ <- doSomethingAConsultation(d)
} yield()
,但它看起來醜陋,但感覺不對。
什麼是榮耀的方式 - 如果有的話 - 堆疊一元效應的使用免費單子什麼時候?
有關這[這裏]的討論(https://www.reddit.com/r/scala/comments/5p3fc3/free_monads_in_scala_web_stack_part_i/dco5yqy/)。要點是使用Free不會讓你無法處理'ConsultationOp'中的值'A'。像[freek](https://github.com/ProjectSeptemberInc/freek)和[eff](https://github.com/atnos-org/eff)這樣的庫可以更加優雅地解決這個問題。 –