Scala 无法使用shapeless派生类型类的隐式实例

Scala 无法使用shapeless派生类型类的隐式实例,scala,shapeless,Scala,Shapeless,我想从一元case类派生类型类的实例。但是当我试图隐式地派生它时,我总是得到一条错误消息。如果我使用隐式方法显式地导出它,它就会工作。我不确定,但可能是因为我在函数中遗漏了一些隐式类型 import shapeless._ import scala.reflect.ClassTag import scala.reflect.runtime.universe.TypeTag sealed trait Foo[A] { def hello(): Unit } object Foo {

我想从一元case类派生类型类的实例。但是当我试图隐式地派生它时,我总是得到一条错误消息。如果我使用隐式方法显式地导出它,它就会工作。我不确定,但可能是因为我在函数中遗漏了一些隐式类型

import shapeless._

import scala.reflect.ClassTag
import scala.reflect.runtime.universe.TypeTag

sealed trait Foo[A] {
  def hello(): Unit
}

object Foo {
  def apply[A](implicit foo: Foo[A]): foo.type = foo

  def instance[A](implicit tag: ClassTag[A]): Foo[A] = new Foo[A] {
    override def hello(): Unit = println(s"Hello from ${tag.runtimeClass.getName}")
  }
}

trait Instances extends LowestPriority {
  implicit val intHelloInstance: Foo[Int] = Foo.instance[Int]
}

trait LowestPriority {
  implicit def derive[A: TypeTag, L <: HList, H](
    implicit gen: Generic.Aux[A, L],
    H: Lazy[Foo[H]],
    isUnary: (H :: HNil) =:= L
  ): Foo[A] =
    new Foo[A] {
      override def hello(): Unit = {
        print(s"Derived: ")
        H.value.hello()
      }
    }
}

object T extends Instances {

  case class A(a: Int)

  def main(args: Array[String]): Unit = {
    intHelloInstance.hello()
//    val a: Foo[A] = derive[A, Int :: HNil, Int] // this works
//    a.hello()
    Foo[A].hello() // error
  }
}
导入无形状_
导入scala.reflect.ClassTag
导入scala.reflect.runtime.universe.TypeTag
封条[A]{
def hello():单位
}
对象Foo{
def apply[A](隐式foo:foo[A]):foo.type=foo
def实例[A](隐式标记:类标记[A]):Foo[A]=新Foo[A]{
重写def hello():Unit=println(s“hello from${tag.runtimeClass.getName}”)
}
}
特征实例扩展了最低优先级{
illInstance中的隐式val:Foo[Int]=Foo.instance[Int]
}
性状低优先级{

隐式定义派生[A:TypeTag,L这是行为取决于隐式解析顺序的情况之一

如果将签名修改为:

  implicit def derive[A, L <: HList, H](
    implicit gen: Generic.Aux[A, L],
    isUnary: (H :: HNil) =:= L, // swapped
    H: Lazy[Foo[H]]             // with this
  ): Foo[A] = ...

implicit def derivate[A,L什么是‘一元’case类?它是一个只有1个参数的case类谢谢!它很有用!但是如果可能的话,你能解释一下这个case类吗(来自doobie):我主要使用此示例作为基础,但在doobie的情况下,它似乎是一个没有隐式重新排序的可行代码。我相信它是有效的,因为存在
C:IsHCons.Aux[L,H,T]
这使得Scala在继续处理其他隐式和类型参数之前正确解析
H
。根据您提供的示例,如果删除它,编译将失败。嗯,这很有趣。再次感谢您,现在我了解了代码失败的原因