Why this code won't compile? Tested on Scala 2.13.6. Is there a way to let scalac know that SizeOfType[Unit]#Size
is actually Short
?
trait SizeOfType[T] {
type Size
def getSize(): Size
}
object SizeOfType {
implicit def unit: SizeOfType[Unit] = new SizeOfType[Unit] {
type Size = Short
def getSize(): Short = 0
}
def test(implicit ev: SizeOfType[Unit]): Short = ev.getSize()
}
[error] type mismatch;
[error] found : ev.Size
[error] required: Short
[error] def test(implicit ev: SizeOfType[Unit]): Short = ev.getSize()
When parameterising with type members instead of type parameters you have to provide type refinement when asking for type class instance, otherwise you are only asking Scala for
SizeOfType[Unit]
and not the intended
SizeOfType[Unit] { type Size = Short }
so something like
implicit val unit: SizeOfType[Unit] { type Size = Short } =
new SizeOfType[Unit] {
type Size = Short
def getSize(): Short = 0
}
def test(implicit ev: SizeOfType[Unit] { type Size = Short }): Short = ev.getSize()
val x: Short = test // ok
Usually you would create dependently typed method and then you can avoid type refinement in the method definition (but it is still needed for definition of type class instance)
implicit val unit: SizeOfType[Unit] { type Size = Short } = ???
def test(implicit ev: SizeOfType[Unit]): ev.Size = ev.getSize()
val x: Short = test // ok
I would suggested studying through "Chapter 4, Working with types and implicits" of underscoreio/shapeless-guide , in particular section which mentions
...If we define the return type as
Second[L]
, theOut
type member will be erased from the return type and the type class will not work correctly.
No, there is no way.
Think about what would happen if you call test
with another implicit value of type SizeOfType[Unit]
which defines type Size = Int
.
Or said differently, the method test
can only infer types based on the trait definition of SizeOfType
, not on one actual implicit value content.
You could however define test
as returning the type ev.Size
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.