Scala-cats:读者组成

问题描述 投票:2回答:1
import cats.data.ReaderT
import cats.instances.either._

trait Service1
trait Service2
case class Cats(name:String)

type FailFast[A] = Either[List[String], A]
type Env = (Service1, Service2, Cats)
type ReaderEnvFF[A] = ReaderT[FailFast, Env, A]

def toReaderEnvFF[A](input:A):ReaderEnvFF[A] =
  ReaderT((_:Env) => Right(input))

def c:ReaderEnvFF[Cats] =
  for {
    cats <- toReaderEnvFF((_:Env)._3)
  } yield cats   // This line is 26

错误:

错误:(26,11)类型不匹配;发现:T1.this.Env => com.savdev.Cats(扩展为)((com.savdev.Service1,com.savdev.Service2,com.savdev.Cats))=> com.savdev.Cats required:com .savdev.Cats}产猫

你能解释一下,为什么猫不是com.savdev.Cats?为什么在错误中,它说它扩展到一个函数与返回方法[Cats],bot not FailFast[Cats]

我尝试应用与此处完全相同的逻辑:

trait Service1 { def s1f = Option(10) }
trait Service2 {
  type ReaderS1[A] = ReaderT[Option,Service1,A]
  import cats.syntax.applicative._
  import cats.instances.option._
  def s2f:ReaderS1[Int] =
    for {
      r2 <- ReaderT((_: Service1).s1f)
      r1 <- 1.pure[ReaderS1]
    } yield r1 + r2
}

在这个例子中,我可以将函数Service1.s1f转换为其结果r2,它工作正常。为什么我不能,例如写下:

for {
 cats <- ReaderT((_:Env)._3)
...
scala scala-cats for-comprehension reader-monad
1个回答
6
投票

toReaderEnvFF((_: Env)._3)cats <- toReaderEnvFF((_: Env)._3)实际上是某些类型toReaderEnvFF[A]((_: Env)._3)A。什么是A现在?由于(_: Env)._3input中的toReaderEnvFF)是Env => Cats类型,因此A类型是Env => Cats。所以toReaderEnvFF((_: Env)._3)ReaderEnvFF[Env => Cats]类型,而cats中的cats <- toReaderEnvFF((_: Env)._3)Env => Cats类型。

x <- SomeMonad[T]变量xT类型(现在SomeMonadReaderEnvFFTEnv => Cats)。

你的第二个例子中的ReaderT((_: Service1).s1f)ReaderT[Option, Service1, Int]类型所以r2中的r2 <- ReaderT((_: Service1).s1f)Int类型。但在你的第一个例子中,toReaderEnvFF((_: Env)._3)的类型为ReaderEnvFF[Env => Cats] aka ReaderT[FailFast, Env, Env => Cats]所以cats中的cats <- toReaderEnvFF((_: Env)._3)Env => Cats类型。这就是区别。

如果你想与ReaderEnvFF[Cats]合作,那么你应该改变cats <- toReaderEnvFF(???)。例如

def c:ReaderEnvFF[Cats] =
  for {
    cats <- toReaderEnvFF(Cats("aaa"))
  } yield cats 
© www.soinside.com 2019 - 2024. All rights reserved.