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。需要的猫:com.savdev.Cats} 养猫
请您解释一下,为什么猫不是com.savdev.Cats
?以及为什么会出现错误,它表示将其扩展为具有返回方法[Cats]
的功能,而不是bot 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)
...
答案 0 :(得分:5)
toReaderEnvFF((_: Env)._3)
,cats <- toReaderEnvFF((_: Env)._3)
中的 toReaderEnvFF[A]((_: Env)._3)
实际上是A
。 A
现在是什么?由于(_: Env)._3
(在input
中又名toReaderEnvFF
)的类型为Env => Cats
,因此类型A
为Env => Cats
。因此toReaderEnvFF((_: Env)._3)
的类型为ReaderEnvFF[Env => Cats]
,cats
中的cats <- toReaderEnvFF((_: Env)._3)
的类型为Env => Cats
。
在x <- SomeMonad[T]
中,变量x
的类型为T
(现在SomeMonad
是ReaderEnvFF
,T
是Env => Cats
)。
ReaderT((_: Service1).s1f)
的类型为ReaderT[Option, Service1, Int]
,因此r2
中的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