本文介绍了无形映射中的子类型多态性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经构建了以下内容:

I've constructed the following:

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

    }
}

上面的代码效果很好,很棒.不过,我还是想要更多.我想,而不是指定我的 HList 将包含列表,而是允许任何 Iterable.像这样:

The above code works great and is awesome. However, I still want more. I would like to, rather than specifying that my HList will contain Lists, allow any Iterable. Like this:

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

    }
}

第二个版本无法编译,显示消息找不到参数映射器的隐式值:shapeless.ops.hlist.Mapper[iterateOverHList.type,shapeless.::[List[Int],shapeless.::[列表 [String],shapeless.HNil]]]".我在这里期望的子类型多态性,即在 Iterable 上工作的函数应该在 List 上工作,由于某种原因失败了.这是为什么?有没有办法让我解决这个问题,或者我自己的贪婪会毁了我?

This second version fails to compile, with the message "could not find implicit value for parameter mapper: shapeless.ops.hlist.Mapper[iterateOverHList.type,shapeless.::[List[Int],shapeless.::[List[String],shapeless.HNil]]]". The subtype polymorphism I'm expecting here, that a function that works on Iterable should work on List, is failing for some reason. Why is that? Is there a way for me to get around this problem, or will my own greed be my undoing?

推荐答案

~> 适用于精确类型.如果您想要 Iterable 的任何子类型的 Poly1,您应该像这样创建它:

~> works with exact types. If you want a Poly1 for any subtype of Iterable you should create it like this:

object iterateOverHList extends Poly1 {
  implicit def iterable[T, L[T] <: Iterable[T]] = at[L[T]](_.iterator)
}

您还可以创建一个 Poly1 来处理某些可以被视为 Iterable 的类型,如下所示:

You could also create a Poly1 that works on some types that could be treated as Iterable like this:

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

这篇关于无形映射中的子类型多态性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-16 01:05