scala - 评估抽象类型成员

标签 scala

为什么这段代码无法编译?在 Scala 2.13.6 上测试。有没有办法让 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()

最佳答案

当使用类型成员而不是类型参数进行参数化时,您必须在请求类型类实例时提供类型细化,否则您只是在向 Scala 请求

SizeOfType[Unit]

而不是预期的

SizeOfType[Unit] { type Size = Short }

类似的东西

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

通常你会创建依赖类型的方法,然后你可以避免在方法定义中进行类型细化(但类型类实例的定义仍然需要它)

implicit val unit: SizeOfType[Unit] { type Size = Short } = ???
def test(implicit ev: SizeOfType[Unit]): ev.Size = ev.getSize()
val x: Short = test // ok

我建议学习 underscoreio/shapeless-guide 的“第 4 章,使用类型和隐式” ,特别是提到的部分

...If we define the return type as Second[L], the Out type member will be erased from the return type and the type class will not work correctly.

关于scala - 评估抽象类型成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67852956/

相关文章:

scala - 为什么聚类似乎在 spark cogroup 函数中不起作用

scala - 使用scala计算与spark的共现项

scala - 带当前行条件的 Spark 窗口函数

scala - 如何使此代码起作用?

xml - Scala XML\\复制 xmlns 属性。为什么以及如何阻止它?

language-agnostic - Scala 中的类型系统是图灵完备的。证明?例子?好处?

scala - 无法导入正则表达式解析器

performance - 访问配置属性的成本是多少?

debugging - Scala:代码仅在调试时运行(等效于#ifdef?)

java - 无法从类路径加载属性文件