I'm learning Scala's concept of manifests and I have a basic understanding how to use it in some simple cases. What puzzles me is what's OptNanifest
and NoManifest
for? I've never seen then used. Can someone give an example where they're are needed/useful?
(I see that Scala 2.10 replaces the concept of Manifest
s with TypeTags
but until 2.10 is final we have to use Manifest
s.)
Suppose we have the following case class and type alias:
scala> case class Foo[A](a: A)
defined class Foo
scala> type F = Foo[_]
defined type alias F
We can now (not very usefully) make a list of things of type F
:
scala> val foos: List[F] = List(Foo(1), Foo("a"), Foo('a))
foos: List[F] = List(Foo(1), Foo(a), Foo('a))
And we can turn this into an array:
scala> foos.toArray
res0: Array[F] = Array(Foo(1), Foo(a), Foo('a))
So clearly the compiler is able to find the manifest it needs as an implicit argument to the toArray
method on List
. But if we ask for a plain old Manifest
for F
, we get an error:
scala> manifest[F]
<console>:11: error: overloaded method value classType with alternatives:
(prefix: scala.reflect.Manifest[_],clazz: Class[_],args: scala.reflect.Manifest[_]*)scala.reflect.Manifest[F] <and>
(clazz: Class[F],arg1: scala.reflect.Manifest[_],args: scala.reflect.Manifest[_]*)scala.reflect.Manifest[F] <and>
(clazz: Class[_])scala.reflect.Manifest[F]
cannot be applied to (java.lang.Class[Foo[_$1]], scala.reflect.Manifest[_$1])
manifest[F]
So it's clear that the compiler is having trouble using manifests to represent the wildcard in our type alias.
The reason toArray
works is that it expects a ClassManifest
, not just a Manifest
. And in fact we can get a ClassManifest
for F
with no problems, precisely because ClassManifest
uses OptManifest
to represent its type arguments—unlike Manifest
, whose type arguments are just other things of type Manifest
.
scala> classManifest[F]
res2: ClassManifest[F] = Foo[<?>]
That <?>
is the string representation of NoManifest
. It plays the role of None
here, allowing the compiler to represent the class information about the type F
(which is all we need for creating an array, fortunately), without saying anything about the type arguments of F
beyond "no, I can't model that".
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