【问题标题】:In scala 2.13, why is it sometimes impossible to summon type class explicitly?在 scala 2.13 中,为什么有时无法显式调用类型类?
【发布时间】:2021-01-08 09:41:52
【问题描述】:

下面是 shapeless 2.3.3 中的一个简单示例:

  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") // works fine

  // summoning Values[_] type class explicitly, the HList & TypeTag are optional
  case class HasValues[T <: HList: TypeTag](v: T) {

    def vs(implicit v: Values[T]): Values[T] = v
  }

  val _vs = HasValues(book).vs

  val v2 = book.values(_vs)

  assert(v2.head == "Benjamin Pierce") // compilation error!

尽管 v2 在语法上与 v1 相同,但最后一行给出了以下错误:

: could not find implicit value for parameter c: shapeless.ops.hlist.IsHCons[com.tribbloids.spike.shapeless_spike.RecordProblem._vs.Out]
one error found

进一步调查表明,符号 v1 的类型层次结构如下:

-+ String :: String :: Int :: Double :: shapeless.HNil
 :       `-+ [ 2 ARGS ] :
 :         !-+ String .................................................................................................................. [0]
 :         : !-+ CharSequence
 :         : : !-+ Object .................................................................................................................. [1]
 :         : :   !-- Any ..................................................................................................................... [2]
 :         : !-- Comparable[String]
 :         : :         `-+ [ 1 ARG ] :
 :         : :           !-- String .................................................................................................................. [0]
 :         : !-- java.io.Serializable .................................................................................................... [3]
 :         !-+ String :: Int :: Double :: shapeless.HNil
 :           :       `-+ [ 2 ARGS ] :
 :           :         !-- String .................................................................................................................. [0]
 :           :         !-+ Int :: Double :: shapeless.HNil
 :           :           :       `-+ [ 2 ARGS ] :
 :           :           :         !-+ Int
 :           :           :         : !-+ AnyVal .................................................................................................................. [4]
 :           :           :         :   !-- Any ..................................................................................................................... [2]
 :           :           :         !-+ Double :: shapeless.HNil
 :           :           :           :       `-+ [ 2 ARGS ] :
 :           :           :           :         !-+ Double
 :           :           :           :         : !-- AnyVal .................................................................................................................. [4]
 :           :           :           :         !-+ shapeless.HNil
 :           :           :           :           !-+ shapeless.HList ......................................................................................................... [5]
 :           :           :           :             !-+ Serializable
 :           :           :           :             : !-- java.io.Serializable .................................................................................................... [3]
 :           :           :           :             !-+ Product
 :           :           :           :             : !-- Equals
 :           :           :           :             !-- Object .................................................................................................................. [1]
 :           :           :           !-- shapeless.HList ......................................................................................................... [5]
 :           :           !-- shapeless.HList ......................................................................................................... [5]
 :           !-- shapeless.HList ......................................................................................................... [5]
 !-- shapeless.HList ......................................................................................................... [5]

但是v2的类型层次省略了大部分信息:

-+ com.tribbloids.spike.shapeless_spike.RecordProblem._vs.Out
 !-+ shapeless.HList
   !-+ Serializable
   : !-+ java.io.Serializable
   :   !-- Any
   !-+ Product
   : !-- Equals
   !-- Object

这是什么原因,如何正确调用Value[_]的类型类?

【问题讨论】:

标签: scala typeclass shapeless scala-2.13


【解决方案1】:

你失去了类型优化。替换

case class HasValues[T <: HList: TypeTag](v: T) {
  def vs(implicit v: Values[T]): Values[T] = v
}

case class HasValues[T <: HList: TypeTag](v: T) {
  def vs(implicit v: Values[T]): Values.Aux[T, v.Out] = v
}

然后两个

val v2 = book.values

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

val v2 = book.values(_vs)

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

编译。

In scala, what is the easiest way to chain functions defined with a type class and of which output type depends on it?

【讨论】:

  • 哇,真的不能太相信自动类型推断。非常感谢您指出。让我尽快验证一下
  • 刚刚验证,类型推导似乎对路径依赖类型和鸭子类型都不起作用。此外,typeTag 可以从一些(非本地)路径相关类型推断出来,但不是鸭子类型。他们可能需要在另一个问题中解决
猜你喜欢
  • 2021-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-21
  • 1970-01-01
  • 2015-02-10
  • 1970-01-01
  • 2020-04-29
相关资源
最近更新 更多