Scala:for-comprehension with guard inside reader
Scala: for-comprehension with guard inside reader
这是代码示例:
type FailFast[A] = Either[List[String], A]
import cats.instances.either._
def f1:ReaderT[FailFast, Map[String,String], Boolean] = ReaderT(_ => Right(true))
def f2:ReaderT[FailFast, Map[String,String], Boolean] = ReaderT(_ => Right(true))
def fc:ReaderT[FailFast, Map[String,String], Boolean] =
for {
b1 <- f1
if (b1)
b2 <- f2
} yield b2
错误是:
Error:(17, 13) value withFilter is not a member of
cats.data.ReaderT[TestQ.this.FailFast,Map[String,String],Boolean]
b1 <- f1
如何将 f1 与 f2 合成。仅当 f1 returns Right(true) 时才必须应用 f2。我通过以下方式解决了它:
def fc2:ReaderT[FailFast, Map[String,String], Boolean] =
f1.flatMap( b1 => {
if (b1)
f2
else ReaderT(_ => Right(true))
})
但我希望有更优雅的解决方案。
- 巨大的
ReaderT[FailFast, Map[String, String], Boolean]
类型很烦人。我用 ConfFF
-shortcut ("map-configured fail-fast") 替换了它;您可能可以找到更好的名称。
- 如果需要,您仍然可以使用
for
-comprehension 语法。
- 无需每次都写出所有
_ =>
和Right(...)
,只需使用applicative
中适当的pure
即可。
因此,您的 fc2
变为:
def fc3: ConfFF[Boolean] =
for {
b1 <- f1
b2 <- if (b1) f2 else true.pure[ConfFF]
} yield b2
完整代码:
import scala.util.{Either, Left, Right}
import cats.instances.either._
import cats.data.ReaderT
import cats.syntax.applicative._
object ReaderTEitherListExample {
type FailFast[A] = Either[List[String], A]
/** Shortcut "configured fail-fast" */
type ConfFF[A] = ReaderT[FailFast, Map[String, String], A]
def f1: ConfFF[Boolean] = ReaderT(_ => Right(true))
def f2: ConfFF[Boolean] = ReaderT(_ => Right(true))
def fc3: ConfFF[Boolean] =
for {
b1 <- f1
b2 <- if (b1) f2 else true.pure[ConfFF]
} yield b2
}
这是代码示例:
type FailFast[A] = Either[List[String], A]
import cats.instances.either._
def f1:ReaderT[FailFast, Map[String,String], Boolean] = ReaderT(_ => Right(true))
def f2:ReaderT[FailFast, Map[String,String], Boolean] = ReaderT(_ => Right(true))
def fc:ReaderT[FailFast, Map[String,String], Boolean] =
for {
b1 <- f1
if (b1)
b2 <- f2
} yield b2
错误是:
Error:(17, 13) value withFilter is not a member of cats.data.ReaderT[TestQ.this.FailFast,Map[String,String],Boolean] b1 <- f1
如何将 f1 与 f2 合成。仅当 f1 returns Right(true) 时才必须应用 f2。我通过以下方式解决了它:
def fc2:ReaderT[FailFast, Map[String,String], Boolean] =
f1.flatMap( b1 => {
if (b1)
f2
else ReaderT(_ => Right(true))
})
但我希望有更优雅的解决方案。
- 巨大的
ReaderT[FailFast, Map[String, String], Boolean]
类型很烦人。我用ConfFF
-shortcut ("map-configured fail-fast") 替换了它;您可能可以找到更好的名称。 - 如果需要,您仍然可以使用
for
-comprehension 语法。 - 无需每次都写出所有
_ =>
和Right(...)
,只需使用applicative
中适当的pure
即可。
因此,您的 fc2
变为:
def fc3: ConfFF[Boolean] =
for {
b1 <- f1
b2 <- if (b1) f2 else true.pure[ConfFF]
} yield b2
完整代码:
import scala.util.{Either, Left, Right}
import cats.instances.either._
import cats.data.ReaderT
import cats.syntax.applicative._
object ReaderTEitherListExample {
type FailFast[A] = Either[List[String], A]
/** Shortcut "configured fail-fast" */
type ConfFF[A] = ReaderT[FailFast, Map[String, String], A]
def f1: ConfFF[Boolean] = ReaderT(_ => Right(true))
def f2: ConfFF[Boolean] = ReaderT(_ => Right(true))
def fc3: ConfFF[Boolean] =
for {
b1 <- f1
b2 <- if (b1) f2 else true.pure[ConfFF]
} yield b2
}