for后如何避免平面图

zer*_*ing 2 scala scala-cats

我有以下代码片段:

(for {
  _ <- LiveUserQuery.make(DbManager.failRollback).create(user)
  - <- IO.sleep(2.seconds)
  a <- router.run(Request(GET, uri"/user/d85ec250-bb5c-11ea-b3de-0242ac130030")).value
} yield a).flatMap {
  case Some(req) =>
    req.as[User].map { u =>
      val is_uuid_valid = u.id.compareTo(UUID.fromString("d85ec250-bb5c-11ea-b3de-0242ac130030")) == 0
      expect(is_uuid_valid) && expect(u.gender == "F")
    }
  case None => expect(false)
}
Run Code Online (Sandbox Code Playgroud)

并想避免flatMap之后for。如何将代码块从 移动flatMapfor

Mat*_*ndt 6

您可以使用一个match表达式:

for {
  _ <- LiveUserQuery.make(DbManager.failRollback).create(user)
  - <- IO.sleep(2.seconds)
  a <- router.run(Request(GET, uri"/user/d85ec250-bb5c-11ea-b3de-0242ac130030")).value
  result <- a match {
    case Some(req) =>
      req.as[User].map { u =>
        val is_uuid_valid = u.id.compareTo(UUID.fromString("d85ec250-bb5c-11ea-b3de-0242ac130030")) == 0
        expect(is_uuid_valid) && expect(u.gender == "F")
      }
    case None => expect(false)
  }
} yield result

Run Code Online (Sandbox Code Playgroud)


Lui*_*rez 6

与 Matthias 类似,但使用fold代替。

for {
  _ <- LiveUserQuery.make(DbManager.failRollback).create(user)
  - <- IO.sleep(2.seconds)
  a <- router.run(Request(GET, uri"/user/d85ec250-bb5c-11ea-b3de-0242ac130030")).value
  result <- a.fold(ifEmpty = expect(false)) { req =>
    req.as[User].map { u =>
      val is_uuid_valid = u.id.compareTo(UUID.fromString("d85ec250-bb5c-11ea-b3de-0242ac130030")) == 0
      expect(is_uuid_valid) && expect(u.gender == "F")
    }
  }
} yield result
Run Code Online (Sandbox Code Playgroud)