1

I tried a example from another post: How do I get around type erasure on Scala? Or, why can't I get the type parameter of my collections?. and following is the workable example:

object Registry {
   import scala.reflect.Manifest

   private var map = Map.empty[Any, (Manifest[_], Any)]

   def register[T](name: Any, item: T)(implicit m: Manifest[T]) {
      map = map.updated(name, m -> item)
   }

   def get[T](key: Any)(implicit m: Manifest[T]): Option[T] = {
     map get key flatMap {
      case (om, s) => if (om <:< m) Some(s.asInstanceOf[T]) else None
   }
  }
}

object App extends App {
   Registry.register("a", List(1, 2, 3))

   println(Registry.get[List[Int]]("a"))
   //Some(List(1, 2, 3))
  }

I have 2 questions:

  1. There is one implicit parameter m: Manifest[T] for method register, I think this parameter should be defined somewhere to be used. But there is no definition, why is it usable?
  2. This line: case (om, s) => if (om <:< m) Some(s.asInstanceOf[T]) else None, in method get, what does om <:< m mean? It is the first time I saw such usage.
Community
  • 1
  • 1
user1484819
  • 899
  • 1
  • 7
  • 18

1 Answers1

1
  1. Manifest implicits are inserted by the compiler (when it can produce them).
  2. om <:< m checks that the type represented by the manifest om is a subtype of the type represented by the manifest m.

Notes:

  • Manifests are replaced by TypeTags in Scala 2.10
  • The <:< method on Manifests is not always accurate (it could e.g. ignore covariance/contravariance annotations on type parameters, IIRC).
Jean-Philippe Pellet
  • 59,296
  • 21
  • 173
  • 234