I was using shapeless tags and wrote code similar to this -
import shapeless.tag
import shapeless.tag.@@
object Typeplay {
trait StringTrait
type MyString = String @@ StringTrait
case class StringClass(mps: MyString)
val stringClass = StringClass(tag[StringTrait]("test"))
}
And this code would not compile. Scala compiler complains about the last line of code saying -
[error] found : String("test")
[error] required: shapeless.tag.Tagged[in.bharathwrites.Typeplay.StringTrait] with String
[error] val stringClass = StringClass(tag[StringTrait]("test"))
I could not understand what was I doing wrong. So I made a small change to my code -
import shapeless.tag
import shapeless.tag.@@
object Typeplay {
trait StringTrait
type MyString = String @@ StringTrait
case class StringClass(mps: MyString)
val stringTag = tag[StringTrait]("test")
val stringClass = StringClass(stringTag)
}
Which is basically just using an explicit variable for the tagging. And this code compiles!!
How can this be? Why does the first program not compile and the second one does?
It seems that type alias confuses type inference in this case. If you provide explicit types to the tag
method, everything works fine:
StringClass(tag[StringTrait][String]("test"))
or
StringClass(tag[StringTrait]("test"):String @@ StringTrait)
or if you declare param StringClass
directly:
case class StringClass(mps: String @@ StringTrait)
StringClass(tag[StringTrait]("test"))
Apparently the limitation of scala compiler.
UPD. Frankly, I can't tell what exact limitation of type inference you hit here. My search for relevant open bugs was fruitless.
Regarding the first example. Everything becomes clear if you look at the implementation of the tag
:
object tag {
def apply[U] = new Tagger[U]
trait Tagged[U]
type @@[+T, U] = T with Tagged[U]
class Tagger[U] {
def apply[T](t : T) : T @@ U = t.asInstanceOf[T @@ U]
}
}
So, when you do this:
tag[StringTrait][String]("test")
You basically do this:
tag.apply[StringTrait].apply[String]("test")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With