我在同一件事上已经完成了一些问题,但似乎无法为我的案例找到解决方案。
本质上我需要定义一个接受x的方法,其中x<:T和l,其中L<:HList并使用在继承自T的每个可能类中定义的Poly1映射到l。
我已经尝试了几种方式,我的最后一次尝试导致了一些非常可怕的scalac炸弹。我必须做一些非常愚蠢的事情,但似乎无法理解它!
import shapeless._
import ops.hlist._
trait T {
val fun: Poly1
}
case class C() extends T {
object fun extends Poly1 {
implicit val caseInt = at[Int](i => "int " + i)
override def toString = "here I am, poly1"
}
}
def method[X <: T](x: X) = x.fun
method(C())
res0: shapeless.Poly1 = here I am, poly1
def method2[X <: T, L <: HList](x: X, l: L)(implicit m: Mapper[x.fun.type, L]) = l map x.fun
method(C(), 23 :: HNil) //BOOM!
答案 0 :(得分:1)
我不知道这是完全你想要什么,但它确实有效:
object test {
import shapeless._
import ops.hlist._
trait T {
type PT <: Singleton with Poly1
val fun: PT
}
object C extends T {
type PT = funImpl.type
object funImpl extends Poly1 {
implicit val caseInt = at[Int](i => "int " + i)
override def toString = "here I am, poly1"
}
val fun = funImpl
}
case class D() extends T {
type PT = funImpl.type
object funImpl extends Poly1 {
implicit val caseInt = at[Int](i => "int " + i)
override def toString = "here I am, poly1"
}
val fun = funImpl
}
def method[X <: T](x: X) = x.fun
val ok = method(C)
// singletonize it
implicit def toOps[X <: T](x: X): Method2Ops[x.type] = { Method2Ops(x: x.type) }
case class Method2Ops[X <: Singleton with T](val x: X) {
def method2[L <: HList](l: L)(implicit m: Mapper[X#PT, L]) = l map (x.fun: X#PT)
}
val okC = C method2 (23 :: HNil)
val d = D()
val okD = d method2 (23 :: HNil)
}