首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scala-cats,带有ReaderT的compose阅读器

Scala-cats,带有ReaderT的compose阅读器
EN

Stack Overflow用户
提问于 2019-03-27 18:35:44
回答 1查看 386关注 0票数 0

下面是一个小的函数组合,所有这些函数都返回ReaderT

代码语言:javascript
复制
  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

代码语言:javascript
复制
def f1:Reader[Map[String,String], Boolean] = Reader(_ => true)

现在我必须编写Reader,这与Reader[FailFast, ...]ReaderT[Id, ...]完全相同

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-27 18:47:24

正如您所提到的,Reader[A, B]只是ReaderT[Id, A, B] (它本身只是Kleisli[Id, A, B]的一个类型别名)。

因为您使用的是cats,所以有一个名为mapK的方法,它映射到ReaderT的第一个类型参数上,您只需要提供一个FunctionK/~>实例来进行转换。所以在你的例子中,它看起来像这样:

代码语言:javascript
复制
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,但由于它看起来有点做作的例子,我将把它留给读者作为练习。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55375125

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档