编译如下:

 object Run1 extends App {

  import shapeless._
  import syntax.std.traversable._

  case class Container[T](x: T)

  Seq(Container(1), Container("x")).toHList[Container[Int] :: Container[String] :: HNil]

}

但这不是:

object Run2 extends App {

  import shapeless._
  import syntax.std.traversable._

  class Container[T](val x: T)

  Seq(new Container(1), new Container("x")).toHList[Container[Int] :: Container[String] :: HNil]

}

失败并显示以下错误:
Error:(40, 52) could not find implicit value for parameter fl: shapeless.ops.traversable.FromTraversable[shapeless.::    [com.adaje.service.table.Run2.Container[Int],shapeless.::[com.adaje.service.table.Run2.Container[String],shapeless.HNil]]]
Seq(new Container(1), new Container("x")).toHList[Container[Int] :: Container[String] :: HNil]
                                               ^

为什么第二个程序不起作用,并且有什么可以添加的呢?

谢谢

最佳答案

FromTraversable类型类需要元素类型的Typeable实例。 Shapeless为案例类提供了现成的功能,但不适用于任意定义的类。不过,您可以很轻松地定义自己的:

import shapeless._, shapeless.syntax.std.traversable._

class Container[T](val x: T)

implicit def containerTypeable[A: Typeable]: Typeable[Container[A]] =
  new Typeable[Container[A]] {
    def cast(t: Any): Option[Container[A]] = t match {
      case c: Container[_] => Typeable[A].cast(c.x).map(new Container(_))
      case _ => None
    }

    def describe: String = s"Container[${ Typeable[A].describe }]"
  }

然后:
scala> val cs = Seq(new Container(1), new Container("x"))
cs: Seq[Container[_ >: String with Int]] = List(Container@3c3c89b2, Container@1273a053)

scala> cs.toHList[Container[Int] :: Container[String] :: HNil]
res0: Option[shapeless.::[Container[Int],shapeless.::[Container[String],shapeless.HNil]]] = Some(Container@357c808b :: Container@607bcaf5 :: HNil)

并且:
scala> cs.reverse.toHList[Container[Int] :: Container[String] :: HNil]
res1: Option[shapeless.::[Container[Int],shapeless.::[Container[String],shapeless.HNil]]] = None

在这种情况下,scalac的-Xlog-implicits选项可能很方便-可以清楚地表明,原始的非案例类尝试中缺少的是Typeable实例。

关于scala - 无形.toHList的行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37015011/

10-10 04:46