-
Notifications
You must be signed in to change notification settings - Fork 531
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Look into type tagging and value classes #644
Comments
Welcome to Scala 2.11.8 (OpenJDK 64-Bit Server VM, Java 1.8.0_91).
Type in expressions for evaluation. Or try :help.
scala> import shapeless._
import shapeless._
scala> import tag._
import tag._
scala> case class A(i:Int) extends AnyVal
defined class A
scala> trait Bar
defined trait Bar
scala> val a = A(1)
a: A = A(1)
scala> tag[Bar](a)
res0: shapeless.tag.@@[A,Bar] = A(1)
scala> Array(res0)
java.lang.ClassCastException: [I cannot be cast to [Ljava.lang.Object;
... 42 elided
scala> Array(tag[Bar](A(1)))
java.lang.ClassCastException: [I cannot be cast to [Ljava.lang.Object;
... 42 elided
scala> trait Baz extends Any
defined trait Baz
scala> Array(tag[Baz](A(1)))
java.lang.ClassCastException: [I cannot be cast to [Ljava.lang.Object;
... 42 elided
scala> val z = tag[Baz](A(1))
z: shapeless.tag.@@[A,Baz] = A(1)
scala> Array(z)
java.lang.ClassCastException: [I cannot be cast to [Ljava.lang.Object;
... 42 elided We'd probably expect the |
It works for Vector: Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_102).
Type in expressions for evaluation. Or try :help.
scala> :pa
// Entering paste mode (ctrl-D to finish)
type @@[T, Tag] = T with Tag
trait Tagger[Tag] { def apply[A](a: A): A @@ Tag = a.asInstanceOf[A @@ Tag] }
def tag[Tag]: Tagger[Tag] = new Tagger[Tag] {}
case class Foo(x: Int) extends AnyVal
trait Bar extends Any
// Exiting paste mode, now interpreting.
defined type alias $at$at
defined trait Tagger
tag: [Tag]=> Tagger[Tag]
defined class Foo
defined trait Bar
scala> Vector(tag[Bar](Foo(1)), tag[Bar](Foo(2)))
res0: scala.collection.immutable.Vector[@@[Foo,Bar]] = Vector(1, 2) |
Welcome to Scala 2.11.8 (OpenJDK 64-Bit Server VM, Java 1.8.0_91).
Type in expressions for evaluation. Or try :help.
scala> object tag {
| def apply[U] = new Tagger[U]
|
| trait Tagged[U] extends Any
| type @@[+T, U] = T with Tagged[U]
|
| class Tagger[U] {
| def apply[T](t : T) : T @@ U = t.asInstanceOf[T @@ U]
| }
| }
defined object tag
scala> case class A(i:Int) extends AnyVal
defined class A
scala> val a = A(1)
a: A = A(1)
scala> trait Bar
defined trait Bar
scala> trait Baz extends Any
defined trait Baz
scala> Array(tag[Baz](a))
res0: Array[tag.@@[A,Baz]] = Array(1)
scala> Array(tag[Bar](a))
res1: Array[tag.@@[A,Bar]] = Array(1) Though I've no idea how to check if those are edit: scala> :t res1
Array[tag.@@[A,Bar]]
scala> res1.getClass
res2: Class[_ <: Array[tag.@@[A,Bar]]] = class [I So even when the trait we're tagging with doesn't extend |
Yes, looks like |
Any idea what the story is with universal traits and binary compatibility? I'm not sure whether we can change that in |
I agree with your suspicion - I would assume it's not a compatible change and would want to see proof that it actually is :D |
The tag is supposed to be erased, so I think there's a fair chance we can get away with this change ... could someone give it a try and attempt to confirm via MiMa? |
Would this extend to |
See the conversation in the typelevel/scala Gitter room on October 11, 2016 8:58 PM.
The text was updated successfully, but these errors were encountered: