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:
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
Can you please explain, why cats is not com.savdev.Cats
? And why in the error, it says that it is expanded to a function with return method [Cats]
, bot not FailFast[Cats]
I try to apply exactly the same logic as here:
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
}
In this example I could convert function Service1.s1f to its result r2 and it works fine. Why I cannot, for instance write something like:
for {
cats <- ReaderT((_:Env)._3)
...
toReaderEnvFF((_: Env)._3)
in cats <- toReaderEnvFF((_: Env)._3)
is actually toReaderEnvFF[A]((_: Env)._3)
for some type A
. What is A
now? Since (_: Env)._3
(aka input
in toReaderEnvFF
) is of type Env => Cats
then type A
is Env => Cats
. So toReaderEnvFF((_: Env)._3)
is of type ReaderEnvFF[Env => Cats]
and cats
in cats <- toReaderEnvFF((_: Env)._3)
is of type Env => Cats
.
In x <- SomeMonad[T]
variable x
is of type T
(now SomeMonad
is ReaderEnvFF
, T
is Env => Cats
).
ReaderT((_: Service1).s1f)
in your second example is of type ReaderT[Option, Service1, Int]
so r2
in r2 <- ReaderT((_: Service1).s1f)
is of type Int
. But in your first example toReaderEnvFF((_: Env)._3)
is of type ReaderEnvFF[Env => Cats]
aka ReaderT[FailFast, Env, Env => Cats]
so cats
in cats <- toReaderEnvFF((_: Env)._3)
is of type Env => Cats
. That's the difference.
If you want to work with ReaderEnvFF[Cats]
then you should change cats <- toReaderEnvFF(???)
. For example
def c:ReaderEnvFF[Cats] =
for {
cats <- toReaderEnvFF(Cats("aaa"))
} yield cats