本文介绍了在 Scala 2.13 中,为什么有时无法显式调用类型类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个在 shapeless 2.3.3 中的简单例子:

Here is a simple example in 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 相同,但最后一行给出了以下错误:

The last line, despite v2 being syntactically identical to v1, gave the following error:

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

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

Further investigation indicates that the type hierarchy of symbol v1 looks like this:

-+ 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 的类型层次结构省略了大部分信息:

But the type hierarchy of v2 omitted most information:

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

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

What's the cause of this and how do I summon the type class of Value[_] properly?

推荐答案

你失去了类型细化.替换

You lost type refinement. Replace

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")

编译.

在 Scala 中,将使用类型类定义的函数以及哪个输出类型依赖于它的最简单方法是什么?

这篇关于在 Scala 2.13 中,为什么有时无法显式调用类型类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 05:14