I'm experimenting with singleton types that contain type parameters. I am trying to write a function that will accept both a Witness for that singleton type and a typeclass for its nested type. It's easy to get each one individually (see f1()
and f2()
below), but I wasn't able to get it to work at the same time:
import shapeless._
import shapeless.labelled.FieldType
import shapeless.syntax.singleton._
sealed trait TC[L]
object TC {
implicit def intTC = new TC[Int] {}
}
object Test {
def f1[VI <: Vector[Int]](value: FieldType[VI, String])(
implicit wt: Witness.Aux[VI]) = {}
def f2[L](value: FieldType[_ <: Vector[L], String])(
implicit wt: TC[L]) = {}
def f3[L, M <: Vector[L]](value: FieldType[M, String])(
implicit wt: TC[L], witness: Witness.Aux[M]) = {}
val v = Vector(1,2,3)
f1(v ->> "foo") // works
f2(v ->> "foo") // works
f3(v ->> "foo") // does not work
}
I am getting
inferred type arguments [Nothing,Test.v.type] do not conform to method f3's type parameter bounds [L,M <: Vector[L]]
[error] f3(v ->> "foo")
Is there a way to help the compiler infer the inner type and a singleton type at the same time?
The following worked for me. I added an implicit parameter ev
that provides evidence that M
is a subclass of Vector[L]
and binds them together. This is sufficient to prevent the compiler to infer that L
is Nothing
.
def f3[L, M <: Vector[_]](value: FieldType[M, String])(
implicit witness: Witness.Aux[M],
ev: M <:< Vector[L],
wt: TC[L]) = {}