首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在scala 2.13中,为什么有时不能显式调用类型类?

在scala 2.13中,为什么有时不能显式调用类型类?
EN

Stack Overflow用户
提问于 2021-01-09 02:57:48
回答 1查看 86关注 0票数 1

这是In scala 2.13, why is it sometimes impossible to summon type class explicitly?的后续问题

以下代码可以正确编译:

代码语言:javascript
运行
复制
  import shapeless._
  import record._
  import syntax.singleton._

  val book =
    ("author" ->> "Benjamin Pierce") ::
      ("title" ->> "Types and Programming Languages") ::
      ("id" ->> 262162091) ::
      ("price" ->> 44.11) ::
      HNil

  val v1 = book.values

  assert(v1.head == "Benjamin Pierce")

  case class HasValues[T <: HList: TypeTag](v: T) {

//    def vs(implicit v: Values[T]) = v // doesn't work
    def vs(implicit v: Values[T]): Values.Aux[T, v.Out] = v // works
  }

  val _vs = HasValues(book).vs

  val v2 = book.values(_vs)

  assert(v2.head == "Benjamin Pierce")

而下面的代码在编译时和运行时在语法上是相同的,编译失败:

代码语言:javascript
运行
复制
  import shapeless._
  import record._
  import syntax.singleton._

  val book =
    ("author" ->> "Benjamin Pierce") ::
      ("title" ->> "Types and Programming Languages") ::
      ("id" ->> 262162091) ::
      ("price" ->> 44.11) ::
      HNil

  val v1 = book.values

  assert(v1.head == "Benjamin Pierce")

  case class HasValues[T <: HList: TypeTag](v: T) {

    type TT = T
  }

  val hv = HasValues(book)

  val _vs = implicitly[Values[hv.TT]]
  val _vs2: Values.Aux[hv.TT, _vs.Out] = _vs

  val v2 = book.values(_vs2)

  assert(v2.head == "Benjamin Pierce")

结果:

代码语言:javascript
运行
复制
[Error] /home/peng/git-spike/scalaspike/common/src/test/scala/com/tribbloids/spike/shapeless_spike/RecordProblem2.scala:41: could not find implicit value for parameter c: shapeless.ops.hlist.IsHCons[com.tribbloids.spike.shapeless_spike.RecordProblem2._vs2.Out]
one error found

此外,下面这行代码看起来很像样板。理想情况下,我认为编译器应该能够自己找出精化,考虑到这完全是向上转换:

代码语言:javascript
运行
复制
  val _vs = implicitly[Values[hv.TT]]
  val _vs2: Values.Aux[hv.TT, _vs.Out] = _vs

为什么第二次编译失败,而且,如何摆脱样板的鸭子类型声明?(当然,不修改类HasValues的签名)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-01-09 21:03:21

implicitly可能会破坏类型优化。请改用shapeless.the

代码

代码语言:javascript
运行
复制
val hv = HasValues(book)

val _vs = the[Values[hv.TT]]
val _vs2: Values.Aux[hv.TT, _vs.Out] = _vs

val v2 = book.values(_vs2)

assert(v2.head == "Benjamin Pierce")

编译。

https://typelevel.org/blog/2014/01/18/implicitly_existential.html

Scala compiler expand types

也是

代码语言:javascript
运行
复制
val hv = HasValues(book)

val _vs2 = the[Values[hv.TT]]

val v2 = book.values(_vs2)

assert(v2.head == "Benjamin Pierce")

代码语言:javascript
运行
复制
val hv = HasValues(book)

val v2 = book.values

assert(v2.head == "Benjamin Pierce")

编译。

另请注意,您可以替换

代码语言:javascript
运行
复制
def vs(implicit v: Values[T]): Values.Aux[T, v.Out] = v

使用

代码语言:javascript
运行
复制
def vs(implicit v: Values[T]): v.type = v
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65634897

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档