如何在Shapeless中实现ToTraversable?

时间:2017-05-18 16:21:56

标签: scala shapeless

我有DL <: HList,我正试图在mkString上使用detailsIn: DL

val detail: String = detailsIn.mkString("", "; ", "")

mkString在Shapeless中定义如下:

  def mkString(start: String, sep: String, end: String)
    (implicit toTraversable: ToTraversable.Aux[L, List, Any]): String = this.toList.mkString(start, sep, end)

我已经看到一些例子定义了一个需要ToTraversable暗示的函数,但是还没有看到任何人真正创造它的价值(我怀疑我在Shapeless中不够精通以便很容易找到这些东西因为我应该能够)。

我有以下片段,我需要填写???,如果这是正确的,我认为一个例子会非常有用:

implicit val dlToList: ToList[DL, Any] = new ToTraversable[DL, List] {???}

但是,我怀疑可能有工厂方法可以做到这一点,但如果是这样,我还没有找到它。

1 个答案:

答案 0 :(得分:3)

您不应该自己实例化此值。相反,你应该要求它作为一个额外的隐式参数,并让编译器完成工作:

def myMethod[DL <: HList](detailsIn: DL)(implicit ev: ToTraversable.Aux[DL, List, Any]) = {
  val detail: String = detailsIn.mkString("", "; ", "")
  println(detail)
}

修改

  1. 请勿使用IntelliJ
  2.   

    如果myMethod可以找到隐含的,为什么mkString找不到呢?

    因为从myMethod的角度来看,您正在为任何ToTraversable[DL, List]寻找DL <: HList!编译器无法弄清楚对于DL的每个可能实例,都可以导出ToTraversable(即使在这种特殊情况下,结构归纳可能也是如此)。

    相反,实际进行调用的地方myMethod(1 :: "s" :: HNil)应该具有隐式解析ToTraversable.Aux[Int :: String :: HNil, List, Any]的所有静态信息。但是你可能会问,如果我不想在通用语境中调用myMethod怎么办?然后你别无选择,只能在调用链中进一步传播隐式约束,直到所有通用性都消失为止。