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)
toReaderEnvFF((_: Env)._3)in cats <- toReaderEnvFF((_: Env)._3)实际上toReaderEnvFF[A]((_: Env)._3)是某种类型的A。A现在是什么?由于(_: Env)._3(aka inputin toReaderEnvFF)是类型,Env => Cats因此类型A是Env => Cats。所以toReaderEnvFF((_: Env)._3)是type ReaderEnvFF[Env => Cats],catsin cats <- toReaderEnvFF((_: Env)._3)是type Env => Cats。
in x <- SomeMonad[T]变量x的类型T(现在SomeMonad是ReaderEnvFF,T是Env => 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]所以cats在cats <- 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)