【问题标题】:Using Either in a Free monad在 Free monad 中使用 Either
【发布时间】:2021-09-04 12:39:43
【问题描述】:

我正在尝试将 Either 作为使用 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 scala-cats either free-monad


    【解决方案1】:

    在此链接中找到解决方案

    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]] =
    

    【讨论】:

      猜你喜欢
      • 2018-02-09
      • 1970-01-01
      • 2018-08-22
      • 1970-01-01
      • 2021-07-28
      • 2012-06-02
      • 1970-01-01
      • 1970-01-01
      • 2020-11-16
      相关资源
      最近更新 更多