繁体   English   中英

斯卡拉猫,用ReaderT组成Reader

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM