To answer your second question, “associating a stable identifier with a type,” one way to do this is to use type classes. Let's say I want to associate a string description with types, I can do it like this:
trait Tag[A] { val desc : String } implicit object StringTag extends Tag[String] { val desc = "character string" } implicit object IntTag extends Tag[Int] { val desc = "32-bit integer" }
Now, to recover such tags, enter implicit magic:
def printTag[T : Tag] { val tag = implicitly[Tag[T]] println("Type is described as : " + tag.desc) }
eg:
printTag[String] // prints "Type is described as : character string" printTag[Double] // compile-time error: no implicit value found of type Tag[Double]
You can even generate tags as needed using implicit functions. For instance:
implicit def liftTagToList[T : Tag] = new Tag[List[T]] { val underlying = implicitly[Tag[T]].desc val desc = "list of " + underlying + "s" }
Now I can do the following:
// prints "Type is described as : list of character strings" printTag[List[String]]
and even:
// prints "Type is described as : list of list of character stringss" printTag[List[List[String]]]
Please forgive pluralization.
source share