Scala-cats:reader-组合
Scala-cats: reader-composition
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
错误:
Error:(26, 11) type mismatch; found : T1.this.Env =>
com.savdev.Cats
(which expands to) ((com.savdev.Service1, com.savdev.Service2, com.savdev.Cats)) => com.savdev.Cats required: com.savdev.Cats }
yield cats
你能解释一下,为什么猫不是 com.savdev.Cats
?为什么在错误中,它说它被扩展为具有 return 方法 [Cats]
的函数,而不是 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)
...
cats <- toReaderEnvFF((_: Env)._3)
中的 toReaderEnvFF((_: Env)._3)
对于某些类型 A
实际上是 toReaderEnvFF[A]((_: Env)._3)
。 A
现在是什么?由于 (_: Env)._3
(又名 toReaderEnvFF
中的 input
)是 Env => Cats
类型,因此 A
类型是 Env => Cats
。所以 toReaderEnvFF((_: Env)._3)
是 ReaderEnvFF[Env => Cats]
类型, cats <- toReaderEnvFF((_: Env)._3)
中的 cats
是 Env => Cats
.
类型
在x <- SomeMonad[T]
中,变量x
的类型是T
(现在SomeMonad
是ReaderEnvFF
,T
是Env => Cats
).
在你的第二个例子中,ReaderT((_: Service1).s1f)
是 ReaderT[Option, Service1, Int]
类型,所以 r2 <- ReaderT((_: Service1).s1f)
中的 r2
是 Int
类型。但是在您的第一个示例中,toReaderEnvFF((_: Env)._3)
是 ReaderEnvFF[Env => Cats]
类型,又名 ReaderT[FailFast, Env, Env => Cats]
,所以 cats <- toReaderEnvFF((_: Env)._3)
中的 cats
是 Env => Cats
类型。这就是区别。
如果您想使用 ReaderEnvFF[Cats]
,那么您应该更改 cats <- toReaderEnvFF(???)
。例如
def c:ReaderEnvFF[Cats] =
for {
cats <- toReaderEnvFF(Cats("aaa"))
} yield 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
错误:
Error:(26, 11) type mismatch; found : T1.this.Env => com.savdev.Cats (which expands to) ((com.savdev.Service1, com.savdev.Service2, com.savdev.Cats)) => com.savdev.Cats required: com.savdev.Cats } yield cats
你能解释一下,为什么猫不是 com.savdev.Cats
?为什么在错误中,它说它被扩展为具有 return 方法 [Cats]
的函数,而不是 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)
...
cats <- toReaderEnvFF((_: Env)._3)
中的 toReaderEnvFF((_: Env)._3)
对于某些类型 A
实际上是 toReaderEnvFF[A]((_: Env)._3)
。 A
现在是什么?由于 (_: Env)._3
(又名 toReaderEnvFF
中的 input
)是 Env => Cats
类型,因此 A
类型是 Env => Cats
。所以 toReaderEnvFF((_: Env)._3)
是 ReaderEnvFF[Env => Cats]
类型, cats <- toReaderEnvFF((_: Env)._3)
中的 cats
是 Env => Cats
.
在x <- SomeMonad[T]
中,变量x
的类型是T
(现在SomeMonad
是ReaderEnvFF
,T
是Env => Cats
).
ReaderT((_: Service1).s1f)
是 ReaderT[Option, Service1, Int]
类型,所以 r2 <- ReaderT((_: Service1).s1f)
中的 r2
是 Int
类型。但是在您的第一个示例中,toReaderEnvFF((_: Env)._3)
是 ReaderEnvFF[Env => Cats]
类型,又名 ReaderT[FailFast, Env, Env => Cats]
,所以 cats <- toReaderEnvFF((_: Env)._3)
中的 cats
是 Env => Cats
类型。这就是区别。
如果您想使用 ReaderEnvFF[Cats]
,那么您应该更改 cats <- toReaderEnvFF(???)
。例如
def c:ReaderEnvFF[Cats] =
for {
cats <- toReaderEnvFF(Cats("aaa"))
} yield cats