Open
Description
Considering the following example where
FooOp[A]
is defined inside a trait which has aT
type parameterBarOp[A]
is defined simply at the top-level
import cats.~>
import iota.TListK.:::
import iota.{CopK, TNilK}
trait Foo[T] {
case class FooOp[A](t: T)
}
case class BarOp[A](s: String)
In the context where T
is still generic, I can define the coproduct of FooOp
and BarOp
as follow:
trait FooBar[T] extends Foo[T] {
type FooBarOp[A] = CopK[FooOp ::: BarOp ::: TNilK, A]
}
Now fixing T
to something specific, I can define two FunctionK
on both FooOp
and BarOp
object FooBarInt extends FooBar[Int]
import FooBarInt._
implicit val FooToOpt: FooOp ~> Option = new (FooOp ~> Option) {
def apply[A](fa: FooOp[A]): Option[A] = None
}
implicit val BarToOpt: BarOp ~> Option = new (BarOp ~> Option) {
def apply[A](fa: BarOp[A]): Option[A] = None
}
But the FunctionK
on the coproduct cannot be summoned
val FooBarToOpt = CopK.FunctionK.summon[FooBarOp, Option]
[error] could not find implicit value for parameter e: cats.arrow.FunctionK[FooBar.this.FooOp,Option]
[error] val FooBarToOpt = CopK.FunctionK.summon[FooBarOp, Option]
[error] ^
Using CopK.FunctionK.of
does not work either
val FooBarToOpt = CopK.FunctionK.of[FooBarOp, Option](FooToOpt, BarToOpt)
[error] Missing interpreter FunctionK[FooBar.this.FooOp, Option]
[error] val FooBarToOpt2 = CopK.FunctionK.of[FooBarOp, Option](FooToOpt, BarToOpt)
[error] ^
Note that the FunctionK
can be implemented by hand so it is legitimate to try to have it implicitly
val manualFooBarToOpt: FooBarOp ~> Option = new (FooBarOp ~> Option) {
val InjFoo = CopK.Inject[FooOp, FooBarOp]
val InjBar = CopK.Inject[BarOp, FooBarOp]
def apply[A](fa: FooBarOp[A]): Option[A] = fa match {
case InjFoo(foo) => FooToOpt(foo)
case InjBar(bar) => BarToOpt(bar)
}
}
The example above has been tested with scala 2.12.8
Metadata
Metadata
Assignees
Labels
No labels