TypeTag and ClassTag

Eyal Roth <[email protected]> Tue, 29 Dec 2015 05:55:03 -0800 (PST)
Newsgroups gmane.comp.lang.scala
Message-ID <[email protected]>
There's something bothering about TypeTag and ClassTag.

According to the documentation, ClassTag merely contains a subset of the 
information in TypeTag, but, in fact, each of them has a 
distinct functionality:

ClassTag makes it possible to check weather any object is of a certain 
generic-type:
def isInstanceOf[A:ClassTag](o: Any) = classTag[A].runtimeClass.isInstance(o
)
AFAIK, one can't achieve that with TypeTag.

Of course, this doesn't cover cases where our generic type is itself a 
class with a generic type; for instance:
isInstanceOf[List[Int]](List("foo")) // returns true, though we would like 
it to return false

For that, we need to store the TypeTag of our generic class:
class MyGenericClass[A](implicit t: TypeTag[A]) { val tag = t }

def isGenericOf[A:TypeTag](o: Any) = o match {
   case gen: MyGenericClass[_] => gen.tag.tpe =:= typeOf[A]
   case _ => false
}

We could do that with ClassTag, but according to this 
<http://stackoverflow.com/questions/34499114/#34499287> StackOverflow 
answer, we'd better use TypeTag.

In this example, we have to use both ClassTag and TypeTag:

trait MyDao {
    def get[A:TypeTag:ClassTag](id: String): A
}


class SingleValueDao extends MyDao {
    var idToValue: Map[String, Any] = Map()
    
    override def get[A:TypeTag:ClassTag](id: String): A = {
        val v = idToValue(id)
        if (classTag[A].runtimeClass.isInstance(v)) v
        else throw new Exception("wrong type")
    }
}

class TypedSeq[A](val seq: Seq[A])(implicit t: TypeTag[A]) {
    val tag = t
}

class MultipleValuesDao extends MyDao {
    var idToValues: Map[String, TypedSeq[_]] = Map()

    override def get[A:TypeTag:ClassTag](id: String): A = {
        val seq = idToValues(id)
        if (seq.tag.tpe =:= typeOf[A]) seq.seq.head.asInstanceOf[A]
        else throw new Exception("wrong type")
    }
}

It would have been more elegant if we could use only one of the "Tag" 
classes.

-- 
You received this message because you are subscribed to the Google Groups "scala-language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.