Search code examples
scalamanifest

What is a Manifest in Scala and when do you need it?


Since Scala 2.7.2 there is something called Manifest which is a workaround for Java's type erasure. But how does Manifest work exactly and why / when do you need to use it?

The blog post Manifests: Reified Types by Jorge Ortiz explains some of it, but it doesn't explain how to use it together with context bounds.

Also, what is ClassManifest, what's the difference with Manifest?

I have some code (part of a larger program, can't easily include it here) that has some warnings with regard to type erasure; I suspect I can solve these by using manifests, but I'm not sure exactly how.


Solution

  • The compiler knows more information about types than the JVM runtime can easily represent. A Manifest is a way for the compiler to send an inter-dimensional message to the code at runtime about the type information that was lost.

    It isn't clear if a Manifest would benefit the errors you are seeing without knowing more detail.

    One common use of Manifests is to have your code behave differently based on the static type of a collection. For example, what if you wanted to treat a List[String] differently from other types of a List:

     def foo[T](x: List[T])(implicit m: Manifest[T]) = {
        if (m <:< manifest[String])
          println("Hey, this list is full of strings")
        else
          println("Non-stringy list")
      }
      
      foo(List("one", "two")) // Hey, this list is full of strings
      foo(List(1, 2)) // Non-stringy list
      foo(List("one", 2)) // Non-stringy list
    

    A reflection-based solution to this would probably involve inspecting each element of the list.

    A context bound seems most suited to using type-classes in scala, and is well explained here by Debasish Ghosh: http://debasishg.blogspot.com/2010/06/scala-implicits-type-classes-here-i.html

    Context bounds can also just make the method signatures more readable. For example, the above function could be re-written using context bounds like so:

      def foo[T: Manifest](x: List[T]) = {
        if (manifest[T] <:< manifest[String])
          println("Hey, this list is full of strings")
        else
          println("Non-stringy list")
      }