有没有一种方法可以从Scala Shapeless中为HList的每个成员派生隐式?

有没有一种方法可以从Scala Shapeless中为HList的每个成员派生隐式?,scala,implicit,shapeless,Scala,Implicit,Shapeless,我尝试了以下方法: type Params = String :: Int :: HNil implicit val params: Params = "hello" :: 5 :: HNil // Supposed to create an implicit for string and int if needed implicit def meberImplicit[A]( implicit params: Params, selector: Selector[Params

我尝试了以下方法:

type Params = String :: Int :: HNil

implicit val params: Params = "hello" :: 5 :: HNil

// Supposed to create an implicit for string and int if needed
implicit def meberImplicit[A](
  implicit 
  params: Params,
  selector: Selector[Params, A]
): A = params.select[A]

// Summoning a string
implicitly[String]    // compile-time error
然而,我得到了一个发散的隐式错误:

diverging implicit expansion for type String

我是不是遗漏了什么?也许已经有了一种内置的或更好的方法来实现这一点?

问题是你太过泛化了:

这样,您基本上为任何值提供了隐式。这与您定义的任何其他隐式参数以及需要获取的任何隐式参数冲突

但是,我们要问为什么编译器不能证明你不能提供给坏的情况下传递给<代码>成员隐式< /代码>,因此它不会认为它是一个可行的选择,所以它能够证明这个分支应该被切断(你不打算去那里),歧义被解决,然后是蛋糕。 问题是,您返回的类型是

A
。这意味着即使您在那里添加了一些约束,例如
A=:!=Params
-虽然正常情况下它可以工作。。。您刚刚提供了所有这些隐式,因此类型约束停止工作,并且突然间,诸如Selector[Params,String]的派生有多种实例化方式。在这种情况下,几乎任何您尝试的实现——只要它返回
A
——都将失败

为了工作,您必须将输出限制为不匹配所有内容的内容-事实上,匹配越少越好。例如,创建一个单独的类型类,用于从HLists中提取值:

trait Extractable[A] { def extract(): A }
object Extractable {
  implicit def extractHList[H <: HList, A](
    implicit
    h: H,
    selector: Selector[H, A]
  ): Extractable[A] = () => selector(h)
}

def extract[A](implicit extractable: Extractable[A]): A = extractable.extract()


错误:值提取不是类型参数H的成员
选择器(H.extract())
请立即尝试,我无意中在那里留下了我看到的旧尝试的一行。我一直怀疑它与返回类型有关。谢谢
trait Extractable[A] { def extract(): A }
object Extractable {
  implicit def extractHList[H <: HList, A](
    implicit
    h: H,
    selector: Selector[H, A]
  ): Extractable[A] = () => selector(h)
}

def extract[A](implicit extractable: Extractable[A]): A = extractable.extract()

extract[String] // "hello"