title: What is the proper way to wrap isInstanceOf[] calls?
body: <p>I'd like to build a wrapper for <code>isInstanceOf[T]</code> and <code>asInstanceOf[T]</code> pair that would output <code>Option[T]</code> with convenient <code>map</code> and <code>getOrElse</code> methods.</p>
  
  <p>So I give a try, but the result has disappointed me.</p>
  
  <pre><code>import scala.reflect.runtime.universe.{TypeTag, typeOf}
  
  class Base()
  class Deep() extends Base
  class Deeper() extends Deep()
  
  final case class WrapSimple[T](source : T) {
    def cast[U] : Option[U] =
      if (source.isInstanceOf[U]) Some(source.asInstanceOf[U]) else None
  }
  
  final case class WrapFullTagged[T: TypeTag](source : T) {
    def cast[U : TypeTag] : Option[U] =
      if (typeOf[T] &lt;:&lt; typeOf[U]) Some(source.asInstanceOf[U]) else None
  }
  
  final case class WrapHalfTagged[T](source : T) {
    val stpe = {
      val clazz = source.getClass
      val mirror = scala.reflect.runtime.universe.runtimeMirror(clazz.getClassLoader)
      mirror.classSymbol(clazz).toType
    }
    def cast[U : TypeTag] : Option[U] =
      if (stpe &lt;:&lt; typeOf[U]) Some(source.asInstanceOf[U]) else None
  }
  
  object Test {
    val base = new Base
    val deep = new Deep
    val deeper = new Deeper
    val wile : Deep = new Deeper
  
    def testSimple() : Unit = {
      println(WrapSimple(deep).cast[Base].isDefined) // should be true
      println(WrapSimple(deep).cast[Deeper].isDefined) // should be false
      println(WrapSimple(wile).cast[Deeper].isDefined) // should be true
    }
  
    def testFullTagged() : Unit = {
      println(WrapFullTagged(deep).cast[Base].isDefined) // should be true
      println(WrapFullTagged(deep).cast[Deeper].isDefined) // should be false
      println(WrapFullTagged(wile).cast[Deeper].isDefined) // should be true
    }
  
    def testHalfTagged() : Unit = {
      println(WrapHalfTagged(deep).cast[Base].isDefined) // should be true
      println(WrapHalfTagged(deep).cast[Deeper].isDefined) // should be false
      println(WrapHalfTagged(wile).cast[Deeper].isDefined) // should be true
    }
  
    def testAll() : Unit = {
      testSimple()
      testFullTagged()
      testHalfTagged()
    }
  }
  </code></pre>
  
  <p><code>WrapSimple</code> looks good, but just does not work, it erases the <code>U</code> type in the <code>isInstanceOf[U]</code> method application, so it is always responds with <code>true</code>. The funny thing is that <code>asInstanceOf[U]</code> keeps the <code>U</code> type normally, so it just produces runtime exceptions.</p>
  
  <p>The second approach I had tried is <code>WrapFullTagged</code> that employs type tags. It seems clear enough, but again plainly breaks the contract. It could only check static types at compile time and has zero insight about actual types in runtime.</p>
  
  <p>So, I breed both approaches and gave birth to the third, that at least produces correct output. But it looks awful and invokes power of reflection that comes with a great cost.</p>
  
  <p>Is it possible to solve the issue with greater elegance? </p>