斯卡拉猫:读者组成

Ale*_*ndr 3 scala for-comprehension reader-monad scala-cats

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
Run Code Online (Sandbox Code Playgroud)

错误:

错误:(26,11)类型不匹配;找到:T1.this.Env => com.savdev.Cats(展开为)(((com.savdev.Service1,com.savdev.Service2,com.savdev.Cats)))=> com.savdev.Cats需要的猫:com .savdev.Cats}产生猫

您能解释一下,为什么猫不是com.savdev.Cats吗?以及为什么在错误中说它被扩展为具有return方法的功能[Cats],而不是botFailFast[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
}
Run Code Online (Sandbox Code Playgroud)

在此示例中,我可以将Service1.s1f函数转换为其结果r2,并且可以正常工作。为什么我不能写这样的东西:

for {
 cats <- ReaderT((_:Env)._3)
...
Run Code Online (Sandbox Code Playgroud)

Dmy*_*tin 6

toReaderEnvFF((_: Env)._3)in cats <- toReaderEnvFF((_: Env)._3)实际上toReaderEnvFF[A]((_: Env)._3)是某种类型的AA现在是什么?由于(_: Env)._3(aka inputin toReaderEnvFF)是类型,Env => Cats因此类型AEnv => Cats。所以toReaderEnvFF((_: Env)._3)是type ReaderEnvFF[Env => Cats]catsin cats <- toReaderEnvFF((_: Env)._3)是type Env => Cats

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

ReaderT((_: Service1).s1f)在您的第二个示例中,类型是,ReaderT[Option, Service1, Int]所以r2in r2 <- ReaderT((_: Service1).s1f)是类型Int。但是,在你的第一个例子toReaderEnvFF((_: Env)._3)是类型ReaderEnvFF[Env => Cats]又名ReaderT[FailFast, Env, Env => Cats]所以catscats <- toReaderEnvFF((_: Env)._3)是类型Env => Cats。就是这样。

如果您想与之合作,ReaderEnvFF[Cats]则应该进行更改cats <- toReaderEnvFF(???)。例如

def c:ReaderEnvFF[Cats] =
  for {
    cats <- toReaderEnvFF(Cats("aaa"))
  } yield cats 
Run Code Online (Sandbox Code Playgroud)