在 yield 中嵌套 for comprehension
Nesting a for comprehension inside a yield
这段代码出现编译错误。我已将其剥离以尽可能简化它。我在这里使用猫 EitherT
monad 转换器。
def foo(
id : String
): EitherT[Future, Err, Either[A, B]] =
for {
a <- f1(id)
} yield {
if (a > 2)
Left(A("Got an a"))
else {
for {
b <- f2() // THIS IS THE PROBLEM
} yield (Right(B("Got a B"))
}
}
编译器抱怨 f2()。它有一个 return 类型的 EitherT[Future,Err,C]
。我得到的编译器错误是:
[error] found : cats.data.EitherT[Future,Err,scala.util.Right[Nothing,B]]
[error] required: Either[A,B]
[error] b <- f2()
我不确定它为什么抱怨这个。我想做 "if" 检查作为对 f2()
调用的保护,但我不能,因为 EitherT
没有 withFilter 方法。有一个更好的方法吗?基本逻辑是,调用 f1()
。如果 a > 2
的值不调用 f2 但如果不是则调用 f2.
尝试使用单个 flatMap
而不是像这样的嵌套 for-comprehensions
case class A(v: String)
case class B(v: String)
case class C(v: String)
def f1(id: String): EitherT[Future, Err, Long] = EitherT.rightT(42)
def f2(): EitherT[Future, Err, C] = EitherT.rightT(C("cc"))
def foo(id : String): EitherT[Future, Err, Either[A, B]] =
f1(id).flatMap { a =>
if (a > 2)
EitherT.rightT(Left(A("Got an A")))
else
f2().map(b => Right(B("Got a B")))
}
foo("123").value.andThen(v => println(v))
输出
Success(Right(Left(A(Got an A))))
但是我同意 Krzysztof 的建议,即 EitherT[Future, Err, Either[A, B]]
模型似乎有点不寻常。
这段代码出现编译错误。我已将其剥离以尽可能简化它。我在这里使用猫 EitherT
monad 转换器。
def foo(
id : String
): EitherT[Future, Err, Either[A, B]] =
for {
a <- f1(id)
} yield {
if (a > 2)
Left(A("Got an a"))
else {
for {
b <- f2() // THIS IS THE PROBLEM
} yield (Right(B("Got a B"))
}
}
编译器抱怨 f2()。它有一个 return 类型的 EitherT[Future,Err,C]
。我得到的编译器错误是:
[error] found : cats.data.EitherT[Future,Err,scala.util.Right[Nothing,B]]
[error] required: Either[A,B]
[error] b <- f2()
我不确定它为什么抱怨这个。我想做 "if" 检查作为对 f2()
调用的保护,但我不能,因为 EitherT
没有 withFilter 方法。有一个更好的方法吗?基本逻辑是,调用 f1()
。如果 a > 2
的值不调用 f2 但如果不是则调用 f2.
尝试使用单个 flatMap
而不是像这样的嵌套 for-comprehensions
case class A(v: String)
case class B(v: String)
case class C(v: String)
def f1(id: String): EitherT[Future, Err, Long] = EitherT.rightT(42)
def f2(): EitherT[Future, Err, C] = EitherT.rightT(C("cc"))
def foo(id : String): EitherT[Future, Err, Either[A, B]] =
f1(id).flatMap { a =>
if (a > 2)
EitherT.rightT(Left(A("Got an A")))
else
f2().map(b => Right(B("Got a B")))
}
foo("123").value.andThen(v => println(v))
输出
Success(Right(Left(A(Got an A))))
但是我同意 Krzysztof 的建议,即 EitherT[Future, Err, Either[A, B]]
模型似乎有点不寻常。