如何从 for-comprehension 中删除折叠?

How to remove a fold from within a for-comprehension?

我在使用 Scalaz 和 Task/EitherT 的 Scala 中有以下代码片段:

def myMethod(request: MyRequest) : EitherT[Task, Failure, Success] =
    EitherT[Task, Failure, Success](
      for {
        aamOpt <- async.findUser(request)
        aamEith <- Task.now(aamOpt.\/>(NoUserFound()))
        result <- aamEith.fold(err => Task.now(-\/(err)), aam => process(aam)).run)
      } yield result)

其中 async.findUser return 是 Task[Option[MyUser]]process(aam) return 是 EitherT[Task, Failure, Success]。这些 return 类型是必需的,因为这些方法与外部服务交互(在线下)。

有什么方法可以将 for comprehension 的最后一行简化为更好的东西吗?我是说这个:

result <- aamEith.fold(err => Task.now(-\/(err)), aam => process(aam)).run)

我可能会立即将 async.findUser 的结果提升到相关的 EitherT monad 中,然后只是 flatMap:

def myMethod(request: MyRequest): EitherT[Task, Failure, Success] =
  EitherT.eitherT[Task, Failure, MyUser](
    async.findUser(request).map(_.\/>(NoUserFound()))
  ).flatMap(process)

这是未经测试的,但类似的东西应该或多或少起作用。