Ich lerne über die Freie Monade in Scala, und ich habe ein einfaches Beispiel für Algebra zusammengestellt, das ich mit Katzen in eine Freie Monade erheben kann.Monadische Effekte in einer Freien Monade in Scala
Hier ist meine Algebra
sealed trait ConsultationOp[A]
object consultation {
case class Create(c: Consultation) extends ConsultationOp[Unit]
case class Get(s: ConsultationId) extends ConsultationOp[Option[Consultation]]
}
Und ich bin in der Lage, es zu benutzen wie
def app = for {
c <- consultation.Create(Consultation("123", "A consultation"))
_ <- consultation.Get(c._id)
} yield()
def interpreters = ConsultationInterpreter or UserInterpreter
app.foldMap(interpreters)
Wo die Hebe ConsultationOp
-Free
implizit durchgeführt wird.
(es gibt eine Menge von Details fehlen, die voll funktionsfähige Implementierung ist hier: https://github.com/gabro/free-api)
So weit so gut, aber was ist, wenn ich ein optionalen Wert von consultation.Get
zurück extrahieren.
Das erste, was in den Sinn kommt, ist eine Monade Transformator, das heißt so etwas wie
def app = for {
c <- consultation.Create(Consultation("123", "A consultation")).liftM[OptionT]
d <- OptionT(consultation.Get(c._id))
_ <- doSomethingAConsultation(d)
} yield()
aber es sieht hässlich, und es fühlt sich nicht richtig.
Was ist der verherrlichte Weg - falls vorhanden - monadische Effekte zu stapeln, wenn eine Free Monade verwendet wird?
Es gibt eine Diskussion zu diesem [hier] (https://www.reddit.com/r/scala/comments/5p3fc3/free_monads_in_scala_web_stack_part_i/dco5yqy/). Das Wesentliche ist, dass die Verwendung von Free Sie nicht davon befreit, den Wert "A" in "ConsultationOp" zu behandeln. Es gibt Bibliotheken wie [freek] (https://github.com/ProjectSeptemberInc/freek) und [eff] (https://github.com/atnos-org/eff), die dieses Problem eleganter lösen. –