I have a toy DSL
case class Logging[A](msg: String, action: A)
case class Persist[A](msg: String, action: A)
type Effect[A] = EitherK[Logging, Persist, A]
that I want to pair with an equally toy interpreter
case class CoLogging[A](run: String => A)
case class CoPersist[A](run: String => A)
type Interp[A] = Tuple2K[CoLogging, CoPersist, A]
Here is an program example:
def prog(implicit L: Logs[Effect], P: Persists[Effect]): Free[Effect, Unit] =
P.store("bar") >> L.log("foo")
and here is the interpreter:
def interpretEffect(implicit CL: CoLogs[IO], CP: CoPersists[IO]): Cofree[Interp, IO[Unit]] =
Cofree.unfold(IO.pure(())) { a: IO[Unit] => Tuple2K(CoLogging(CL.coLog(a)), CoPersist(CP.coPersist(a))) }
I've paid due diligence and defined functors as well as injection implicits. The compiler complains that it cannot find an instance cats.Functor[[A]cats.data.Tuple2K[example.CoLogging,example.CoPersist,A]]
, even though I am importing cats.data.Tuple2K._
where the instance is implicitly defined.
I can't see what I'm doing wrong, it must be something stupid. Do you have any idea? All the code can be seen in this gist.
The compiler complains that it cannot find an instance
cats.Functor[[A]cats.data.Tuple2K[example.CoLogging,example.CoPersist,A]]
, even though I am importingcats.data.Tuple2K._
where the instance is implicitly defined.
Functor[Tuple2K[F, G, ?]]
is defined via Tuple2KInstances8#catsDataFunctorForTuple2K
if Functor[F]
and Functor[G]
were defined. The thing is that Functor[CoLogging]
and Functor[CoPersist]
weren't.
Add
object CoLogging {
implicit val coLoggingFunctor: Functor[CoLogging] = new Functor[CoLogging] {
override def map[A, B](fa: CoLogging[A])(f: A => B): CoLogging[B] = CoLogging(fa.run andThen f)
}
}
and
object CoPersist {
implicit val coPersistFunctor: Functor[CoPersist] = new Functor[CoPersist] {
override def map[A, B](fa: CoPersist[A])(f: A => B): CoPersist[B] = CoPersist(fa.run andThen f)
}
}
and everything should compile.
The thing is the order of implicits. Move object functors
to the beginning and everything should compile.