scala - 在scala 2.13中,为什么有时无法显式调用类型类?

标签 scala typeclass shapeless scala-2.13

这是 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[_] 的类型类?

最佳答案

你失去了类型优化。替换

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?

关于scala - 在scala 2.13中,为什么有时无法显式调用类型类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65618971/

相关文章:

scala - 未找到 LabelledGeneric 的无形映射器

scala - Spark scala中运行时间戳差异

scala - 无法将 scala-reflect 添加为依赖项

string - IsString 实例不会自动转换为 String

scala - 如何将函数映射到函数的 HList 从某种类型到某种类型?

scala - 从展平元组创建嵌套通用案例类

Scala 工作表无法解析类名 - IntelliJ IDEA

scala - 动态字符串插值

scala - 在范围内显示时未找到隐式

haskell - 为什么 ghci 输出 (Num a) => a for :t 4 and not (Ord a) => a?