[英]Scala-cats, compose Reader with ReaderT
这是一小部分函数,所有函数都返回ReaderT
:
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
返回Reader
而不是ReaderT
,如何实现fc
:
def f1:Reader[Map[String,String], Boolean] = Reader(_ => true)
现在,我必须ReaderT[Id, ...]
Reader
,它与Reader[FailFast, ...]
恰好是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
但是由于它看起来像是一个EitherT
示例,因此我将其留给读者练习。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.