gpt4 book ai didi

scala - 在 Free monad 中使用任一

转载 作者:行者123 更新时间:2023-12-04 07:29:00 26 4
gpt4 key购买 nike

我正在尝试使用一个作为使用 Free monad 的代数的结果,如下面的代码


///// Command
sealed trait Command[A]

type Result[A] = Either[Exception, A]

object Command {
case class Tell(line: String) extends Command[Result[Unit]]

case class Ask(line: String) extends Command[Result[String]]

}
  type App[A] = EitherK[Command, Log, A]

def program(implicit L: LogOps[App],
C: CommandOps[App]): Free[App, Unit] =
for {
_ <- L.show("start <ask>")
name <- C.ask("What's your name?")
_ <- L.show("start <tell>")
_ <- C.tell(s"Hi <$name>, nice to meet you!")
_ <- L.show("done.")
} yield ()

...

问题是名字是一个Either,所以我得到了以下输出
L--- start <ask>
What's your name?
George
L--- start <tell>
Hi <Right(George)>, nice to meet you!
L--- done.
任何的想法?
谢谢

最佳答案

在此链接中找到的解决方案
Scala Free Monads with Coproduct and monad transformer
我必须定义一个像下面这样的函数

def liftFE[F[_], T[_], A, B](f: T[Either[A, B]])(implicit I: InjectK[T, F]): EitherT[Free[F, *], A, B] = EitherT[Free[F, *], A, B](Free.liftF(I.inj(f)))

并使用它代替 Free.inject喜欢关注
  class CommandOps[F[_]](implicit I: InjectK[Command, F]) {

import Command.{Ask, Tell}

def tell(line: String): EitherT[Free[F, *], Exception, Unit] =
liftFE(Tell(line))

def ask(line: String): EitherT[Free[F, *], Exception, String] =
liftFE(Ask(line))
}

并更改“程序”结果类型
  def program(implicit L: LogOps[App],
C: CommandOps[App]): EitherT[Free[App, *], Exception, Either[Exception, Unit]] =

关于scala - 在 Free monad 中使用任一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68057799/

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