Scala-cats,用 ReaderT 组合 Reader
Scala-cats, compose Reader with ReaderT
这里是函数的小组合,全部returnReaderT
:
type FailFast[A] = Either[List[String], A]
def f1:ReaderT[FailFast, Map[String,String], Boolean] = ReaderT(_ => Right(true))
def f2:ReaderT[FailFast, Map[String,String], Boolean] = ReaderT(_ => Left(List("d")))
def f3:ReaderT[FailFast, Map[String,String], Boolean] = ReaderT(_ => Right(true))
def f4:ReaderT[FailFast, Map[String,String], Boolean] = ReaderT(_ => Right(true))
def fc:ReaderT[FailFast, Map[String,String], Boolean] =
f1.flatMap( b1 => {
if (b1)
for {
b2 <- f2
b3 <- f3
b4 <- f4
} yield b4
else ReaderT(_ => Right(true))
})
如果 f1
会 return Reader
,但不会 ReaderT
:
,如何实施 fc
def f1:Reader[Map[String,String], Boolean] = Reader(_ => true)
现在我必须合成 Reader
,这正好是 ReaderT[Id, ...]
和 Reader[FailFast, ...]
正如您提到的 Reader[A, B]
只是 ReaderT[Id, A, B]
(它本身只是 Kleisli[Id, A, B]
的类型别名)。
由于您使用的是猫,因此有一个名为 mapK
的方法映射到 ReaderT
的第一个类型参数,您只需提供一个 FunctionK/~>
实例进行转换。所以在你的情况下它看起来像这样:
val Id2FailFast = new (Id ~> FailFast) {
def apply[T](f: Id[T]): FailFast[T] = Right(f)
}
f1.mapK(Id2FailFast).flatMap( b1 => {
if (b1)
for {
b2 <- f2
b3 <- f3
b4 <- f4
} yield b4
else ReaderT(_ => Right(true))
})
可能还有一些其他的重构可以进一步清理它,比如使用 EitherT
但由于它看起来有点人为的例子,我将把它留作 [=24 的练习=].
这里是函数的小组合,全部returnReaderT
:
type FailFast[A] = Either[List[String], A]
def f1:ReaderT[FailFast, Map[String,String], Boolean] = ReaderT(_ => Right(true))
def f2:ReaderT[FailFast, Map[String,String], Boolean] = ReaderT(_ => Left(List("d")))
def f3:ReaderT[FailFast, Map[String,String], Boolean] = ReaderT(_ => Right(true))
def f4:ReaderT[FailFast, Map[String,String], Boolean] = ReaderT(_ => Right(true))
def fc:ReaderT[FailFast, Map[String,String], Boolean] =
f1.flatMap( b1 => {
if (b1)
for {
b2 <- f2
b3 <- f3
b4 <- f4
} yield b4
else ReaderT(_ => Right(true))
})
如果 f1
会 return Reader
,但不会 ReaderT
:
fc
def f1:Reader[Map[String,String], Boolean] = Reader(_ => true)
现在我必须合成 Reader
,这正好是 ReaderT[Id, ...]
和 Reader[FailFast, ...]
正如您提到的 Reader[A, B]
只是 ReaderT[Id, A, B]
(它本身只是 Kleisli[Id, A, B]
的类型别名)。
由于您使用的是猫,因此有一个名为 mapK
的方法映射到 ReaderT
的第一个类型参数,您只需提供一个 FunctionK/~>
实例进行转换。所以在你的情况下它看起来像这样:
val Id2FailFast = new (Id ~> FailFast) {
def apply[T](f: Id[T]): FailFast[T] = Right(f)
}
f1.mapK(Id2FailFast).flatMap( b1 => {
if (b1)
for {
b2 <- f2
b3 <- f3
b4 <- f4
} yield b4
else ReaderT(_ => Right(true))
})
可能还有一些其他的重构可以进一步清理它,比如使用 EitherT
但由于它看起来有点人为的例子,我将把它留作 [=24 的练习=].