In Scala, is it possible to get the "val" referenced by a singleton type?

I am trying to get the minimal form of dependent types in Scala. if I have

class A[T <: Int] val x: Int = 7 

I can

 val a = new A[x.type] 

Now can I restore x from its singleton x.type ?

Or, if this is not possible, is it possible to associate a stable identifier with some type and then extract it?

+4
source share
2 answers

No, you cannot restore x from x.type due to JVM type erasure. For example, how to implement this?

 def f[A]: A = ??? f[x.type] 

At the JVM bytecode level, there is no way for f find the x: A value given by A = x.type because it has nothing to work with: all type parameters are lost at runtime, and the x value is not available on the f stack.

For the same reason, in order to get a stable type identifier, you will need to confirm it as a Manifest value. But when I tried, I get a weird result,

 def f[A : Manifest] = implicitly[Manifest[A]] val x = "hi" val y = "ho" println(f[x.type]) // hi.type println(f[y.type]) // ho.type f[x.type] == f[y.type] // true !? 

I'm not sure why these two types of manifest are equal - they even have different toString views. Could this be a Scala bug? Update: according to ScalaDoc , relationship operators like <: <and =: = should only be considered approximations, since there are numerous aspects of type matching that are not yet sufficiently represented in the manifest.

To summarize, overriding type information into runtime values ​​does not happen automatically on the JVM. Scala Manifest should fill the gap, but I think it does not work with dependent types.

+6
source

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.

+3
source

All Articles