首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >cats.ReaderT[F,A,B]来自for-comprehension中的依赖项A

cats.ReaderT[F,A,B]来自for-comprehension中的依赖项A
EN

Stack Overflow用户
提问于 2019-07-19 15:17:08
回答 2查看 110关注 0票数 1

下面是一个用例:

代码语言:javascript
复制
import cats.data.ReaderT
trait Service{
  type OptionFromMap[A] = ReaderT[Option, Map[String, String], A]
  def f1(nameKey:String): OptionFromMap[String] = ReaderT(_.get(nameKey))
  def f2(addressKey:String, name:String): OptionFromMap[String] =
    ReaderT(map => Option(s"name: $name, address: ${map(addressKey)}"))
}
trait Service2 {
  type Env = (Service, Map[String,String])
  type OptionFromEnv[A] = ReaderT[Option, Env, A]
  import cats.syntax.applicative._
  import cats.instances.option._
  def f(nameKey:String, addressKey:String): OptionFromEnv[String] =
    for {
      //wrong try:
      s1 <- ReaderT((_:Env) => Option((_:Env)._1))
      //wrong try:
      s2 <- (_:Env).pure[OptionFromEnv]
      name <- s1.f1(nameKey).local((_: Env)._2)
      r <- s1.f2(addressKey, name).local((_: Env)._2)
    } yield r
}

所以我希望能够调用Servicef1f2方法。

问题是如何在for- question中实现它。通过ReaderT.apply,我可以通过以下方式完成:

代码语言:javascript
复制
  def c(nameKey:String, addressKey:String): OptionFromEnv[String] =
    ReaderT(env =>
      (for {
        name <- env._1.f1(nameKey).local((_: Env)._2)
        r <- env._1.f2(addressKey, name).local((_: Env)._2)
      } yield r)
      .run(env)
    )

但我试图实现一些东西,看起来是这样的:

代码语言:javascript
复制
import cats.data.Reader
trait Service{
  def f1: Reader[Map[String, Int], Int] = Reader(_("name"))
  def f2: Reader[Map[String, Int], Int] = Reader(_("age"))
}
trait Service2 {
  type Env = (Service, Map[String,Int])
  def f(i: Int): Reader[Env, Int] =
    for {
      s <- Reader((_: Env)._1)          //extract input type Service 
      r1 <- s.f1.local((_: Env)._2)
      r2 <- s.f2.local((_: Env)._2)
    } yield r1 + r2 + i
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-07-19 16:45:24

尝试替换

代码语言:javascript
复制
//wrong try:
s1 <- ReaderT((_:Env) => Option((_:Env)._1))

使用

代码语言:javascript
复制
s1 <- ReaderT((env: Env) => Option(env._1))
票数 3
EN

Stack Overflow用户

发布于 2019-10-17 15:47:40

找到了通过Kleisli.ask解决该问题的其他方法。不能说哪个选项更好。作为另一种选择:

代码语言:javascript
复制
trait Service2 {

  def f(nameKey:String, addressKey:String): OptionFromEnv[String] =
    for {
      env <- Kleisli.ask[Option, Env]
      s <- Kleisli.pure(env._1)
      name <- env._1.f1(nameKey).local((_: Env)._2)
      r <- s.f2(addressKey, name).local((_: Env)._2)
    } yield r
}

一般来说,我们有一种方法可以访问env,在for- general内部。当然,也没有必要从env获取s

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

https://stackoverflow.com/questions/57107370

复制
相关文章

相似问题

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