I am having trouble resolving a scala.reflect.Manifest for a type with a type member.
For example,
import scala.reflect.Manifest
trait Foo {
type T
}
trait Bar[T]
object Main extends App {
val barM: Manifest[Bar[Int]] =
implicitly[Manifest[Bar[Int]]]
val fooM: Manifest[Foo{type T = Int}] =
implicitly[Manifest[Foo{type T = Int}]]
}
The above code does not compile, giving the following error.
Foo.scala:15: error: type mismatch;
found : scala.reflect.Manifest[Foo]
required: scala.reflect.Manifest[Foo{type T = Int}]
Note: Foo >: Foo{type T = Int}, but trait Manifest is invariant in type T.
You may wish to investigate a wildcard type such as `_ >: Foo{type T = Int}`. (SLS 3.2.10)
implicitly[Manifest[Foo{type T = Int}]]
^
one error found
But the barM declaration works just fine.
I am aware that type members are not quite type parameters, but I am definitely not up on all the subtleties.
How can one go about resolving a Manifest for a type with a concrete type member?
Structural types are not supported by Manifest. SI-4252 (Manifest of structural types) is labelled as "won't fix", and it is recommended that you use TypeTag instead. Manifest is also likely to be deprecated soon.
scala> import scala.reflect.runtime.universe.TypeTag
import scala.reflect.runtime.universe.TypeTag
scala> implicitly[TypeTag[Foo { type T = Int} ]]
res18: reflect.runtime.universe.TypeTag[Foo{type T = Int}] = TypeTag[Foo{type T = Int}]
You might also be able to work around this with a type alias, but it's hard to tell without a use-case.
scala> type FooAux[T] = Foo { type T }
defined type alias FooAux
// Compiles, but is it useful?
scala> implicitly[Manifest[FooAux[Int]]]
res19: scala.reflect.Manifest[FooAux[Int]] = Foo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With