簡體   English   中英

用於理解的不同 monad

[英]Different monads in for comprehension

我有以下代碼


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 獲取布爾值,然后只有當 sendMessage 返回 true 時,我才想調用 anotherMethod。

我知道它們是不同的單子。 請讓我知道一種更簡潔的方式,我可以如何添加所有三個調用以進行理解。 感謝幫助

不幸的是,EitherT 和 Task 是不同的 monads,並且 monads 不能組合,所以你不能直接使用它們來理解。

您可以做的是將 Task 提升到 ThatiT 中,但在這種情況下,EitherT 的類型參數 F 必須是 Task,而在您的情況下,它是 Future。

所以你必須做兩件事:

  1. 將任務轉化為未來
  2. 將未來提升到任一個

假設您的另一種方法如下所示:

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-comprehension 中有條件地使用 effect:

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
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM