Чтобы ответить на ваш второй вопрос, «связать стабильный идентификатор с типом», один из способов сделать это - использовать классы типов. Допустим, я хочу связать описание строки с типами, я могу сделать это следующим образом:
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"
}
Теперь, чтобы восстановить такие теги, введите неявную магию:
def printTag[T : Tag] {
val tag = implicitly[Tag[T]]
println("Type is described as : " + tag.desc)
}
например:
printTag[String] // prints "Type is described as : character string"
printTag[Double] // compile-time error: no implicit value found of type Tag[Double]
Вы даже можете создавать теги по мере необходимости, используя неявные функции. Например:
implicit def liftTagToList[T : Tag] = new Tag[List[T]] {
val underlying = implicitly[Tag[T]].desc
val desc = "list of " + underlying + "s"
}
Теперь я могу сделать следующее:
// prints "Type is described as : list of character strings"
printTag[List[String]]
и даже:
// prints "Type is described as : list of list of character stringss"
printTag[List[List[String]]]
Пожалуйста, прости множественное число.