我正在尝试使用 shapeless 的 hlist 来构建可自省的 URL 模板,但是在遍历我的 HList 时遇到了麻烦。以下内容无法编译:
import shapeless.{::, HList, HNil}
import shapeless.LUBConstraint._
import shapeless.ops.hlist.ToTraversable._
import scala.util.Try
import shapeless.ops.hlist._
object Path {
def /(s: String) = Path(PathLiteral(s) :: HNil)
def param[T](name: String) = PathParameter(name)
}
sealed trait PathSegment[+T]
case class PathLiteral(value: String) extends PathSegment[String]
case class PathParameter[+T](name: String) extends PathSegment[T]
case class Path[L <: HList : <<:[PathSegment[_]]#λ](segments: L)
(implicit ev: ToList[L, PathSegment[_]])
{
def /(literal: String) = Path(PathLiteral(literal) :: segments)
def /[T](param: PathParameter[T]) = Path(param :: segments)
override def toString: String = s"Path(${segments.toList.reverse})"
}
object Test extends App {
import Path.param
val myPath = Path / "v1" / "pets" / param[String]("name") / "pictures"
println(myPath)
}
在我看来,ToTraversable._
导入涵盖了 HNil 情况以及具有 HList 的尾部和具有相同最小上限的新头部的情况。显然,我要么错过了导入,要么误解了一切。
我不确定将类中的证据作为隐式参数缓存是否符合规定;我这样做是因为
- 我不希望 hlist 详细信息泄漏到外部 API
- 我需要它来获得一个不错的 toString