我构建了以下内容:
import shapeless._
import poly._
object Main {
def main(args: Array[String]) = {
object iterateOverHList extends (List ~> Iterator) {
def apply[T](it: List[T]) = it.iterator
}
val x = List(1,2,3) :: List("cat","dog") :: HNil
val xIt = x map iterateOverHList
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码很棒,非常棒.但是,我还想要更多.我想,而不是指定我的HList将包含列表,允许任何Iterable.像这样:
import shapeless._
import poly._
object Main {
def main(args: Array[String]) = {
object iterateOverHList extends (Iterable ~> Iterator) {
def apply[T](it: Iterable[T]) = it.iterator
}
val x = List(1,2,3) :: List("cat","dog") :: HNil
val xIt = x map iterateOverHList
}
}
Run Code Online (Sandbox Code Playgroud)
第二个版本无法编译,消息"无法找到参数映射器的隐式值:shapeless.ops.hlist.Mapper [iterateOverHList.type,shapeless.:: [List [Int],shapeless.:: [List [String] ],shapeless.HNil]]]".我在这里期待的子类型多态性,一个在Iterable上工作的函数应该在List上工作,由于某种原因失败了.这是为什么?有没有办法让我解决这个问题,还是我自己的贪婪是我的毁灭?
~>适用于确切类型.如果你想要Poly1任何子类型,Iterable你应该像这样创建它:
object iterateOverHList extends Poly1 {
implicit def iterable[T, L[T] <: Iterable[T]] = at[L[T]](_.iterator)
}
Run Code Online (Sandbox Code Playgroud)
您还可以创建一个Poly1适用于某些类型的类型,可以这样处理Iterable:
import scala.collection.generic.IsTraversableOnce
object iterateOverHList extends Poly1 {
implicit def iterable[L](implicit i: IsTraversableOnce[L]) =
at[L](i.conversion(_).toIterator)
}
val x = "abc" :: List(1,2,3) :: HNil
val xIt = x map iterateOverHList
// xIt: shapeless.::[Iterator[Char],shapeless.::[Iterator[Int],shapeless.HNil]] = non-empty iterator :: non-empty iterator :: HNil
Run Code Online (Sandbox Code Playgroud)