[英]evaluation of an abstract type member
Why this code won't compile?为什么这段代码不能编译? Tested on Scala 2.13.6.
在 Scala 2.13.6 上测试。 Is there a way to let scalac know that
SizeOfType[Unit]#Size
is actually Short
?有没有办法让 scalac 知道
SizeOfType[Unit]#Size
实际上是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当使用类型成员而不是类型参数进行参数化时,您必须在要求类型 class 实例时提供类型细化,否则您只要求 Scala
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)通常你会创建依赖类型的方法,然后你可以避免方法定义中的类型细化(但它仍然需要定义类型 class 实例)
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我建议通过underscoreio/shapeless-guide的“第 4 章,使用类型和隐含”进行学习,特别是其中提到的部分
...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....如果我们将返回类型定义为
Second[L]
,则Out
类型成员将从返回类型中删除,并且类型 class 将无法正常工作。
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
.想想如果你用另一个定义
type Size = Int
的SizeOfType[Unit]
类型的隐式值调用test
会发生什么。
Or said differently, the method test
can only infer types based on the trait definition of SizeOfType
, not on one actual implicit value content.或者换一种说法,方法
test
只能根据SizeOfType
的 trait 定义来推断类型,而不是根据一个实际的隐含值内容。
You could however define test
as returning the type ev.Size
.但是,您可以将
test
定义为返回类型ev.Size
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.