scala - 不同的单子(monad)用于理解

标签 scala scala-cats monad-transformers monix

我有以下代码


def processInfoAndReturnResponse(input: Input]): EitherT[Future, CustomException, A] = ???

def sendMessage(message: A): monix.eval.Task[Boolean] = ???

def anotherMethod(message: Input): Future[Either[CustomException, Unit]]= ???
def integrate(): Future[Either[GoogleException, A]] = {
(for {
  response <- processInfoAndModelResponse(input)
  _ <- EitherT.liftF[Future, CustomException, A](sendMessage(response).map(_ => response).runToFuture
}yield response).value

到目前为止,一切都很好。但现在,我想从 sendMessage 获取 bool 值,然后只有当 sendMessage 返回 true 时,我才想调用 anotherMethod。

我知道它们是不同的单子(monad)。请让我知道如何添加所有三个调用以供理解的更清晰的方法。感谢帮助

最佳答案

不幸的是,EitherT 和 Task 是不同的 monad,并且 monad 不能组合,因此您不能直接在同一个 monad 中使用它们来进行理解。

您可以做的是将 Task 提升到 EitherT,但在这种情况下,EitherT 的类型参数 F 必须是 Task,而在您的情况下,它是 Future。

所以你必须做两件事:

  1. 将任务转变为 future
  2. 为 EitherT 提升 future

假设您的另一种方法如下所示:

def anotherMethod(input: Integer): EitherT[Future, Exception, Unit] = EitherT.rightT[Future, Exception](())

所以你的理解可能如下所示:

import cats.implicits._
import scala.concurrent.ExecutionContext.Implicits._

val prog = for {
    //you need to use leftWiden adjust left of either to common type
    response <- processInfoAndReturnResponse(inp).leftWiden[Exception]
    //running task to Future and then lifting to EitherT
    i <- EitherT.liftF[Future, Exception, Integer](sendMessage(response).runToFuture)
    _ <- anotherMethod(i)
} yield ()

//prog is of type EitherT so we have to unwrap it to regular Future with rethrowT
val future: Future[Unit] = prog.rethrowT

要在编辑后回答您的问题,您可以使用 whenA 在 for 理解中有条件地使用效果:

def integrate(): Future[Either[GoogleException, A]] ={
  (for {
    response <- processInfoAndModelResponse(input)
    sendStatus <- EitherT.liftF[Future, CustomException, Boolean](sendMessage(response).runToFuture)
    finalresult <- anotherMethod(input).whenA(sendStatus)
  } yield finalresult).value
}

关于scala - 不同的单子(monad)用于理解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64069227/

相关文章:

scala - 如何发布带有校验和(MD5、SHA1)的工件?

scala - 如何修复 Scala 中案例类集合的约束

scala - 如何使用 IO monad 编写猫的理解力

scala - 测试中*的含义是什么?

haskell - Monad 变压器和提升功能

scala - 如何在Scala测试中检查 “Either”结果?

java - 如何让 sbt 在发布到 Maven 存储库时用实际日期替换 SNAPSHOT?

scala - 导入 FlatMap 实例会破坏应用构建器语法

haskell - Haskell 中不同的、交互的状态级别

parsing - 使普通的一元函数与等效的一元转换器一起工作