如何解决为什么在调用这种较高类型的类型的collect时,类型信息会丢失?
我试图熟悉Scala中类型较高的类型,因此我尝试实现这种简单的方法,该方法采用Option
的可遍历并将其平整,就像平整它一样。但是,由于函数返回类型Traversable[Any]
而不是T[S]
,所以编译器将引发错误。为什么会这样,如何使它正常工作?
def flatten[S,T[_] <: Traversable[_]](list: T[Option[S]]): T[S] = {
list.collect({ case Some(s) => s })
}
我认为可能是我错误地定义了T
的类型,但是我也尝试了T[_]: Traversable
和T[X] <: Traversable[X]
,但它们都不起作用。
当然可以,
def flatten[S](list: Traversable[Option[S]]): Traversable[S] = {
list.collect({ case Some(s) => s })
}
但是我不想丢失有关返回类型的输入类型信息(调用flatten(List[Option[T]])
应该返回List[T]
。
解决方法
这是因为collect
不返回T
,而仅返回Traversable
。特质Traversable
不知道继承它的任何类的类型。
此外,您的较高型类型是错误的,应该使用T[x] <: Traversable[x]
以避免存在类问题。您可以执行以下操作:
def flatten[S,T[x] <: Traversable[x]](list: T[Option[S]])(
implicit ev: collection.generic.CanBuildFrom[Traversable[Option[S]],S,T[S]]
): T[S] = list.collect { case Some(s) => s }
,否则Luis MiguelMejíaSuárez建议使用类型类可能会更好。我还建议尽可能使用Scala 2.13。
trait Flatten[F[_]] {
def flatten[S](list: F[Option[S]]): F[S]
}
object Flatten {
def flatten[S,F[_]](list: List[Option[S]])(implicit f: Flatten[F]) = f.flatten(list)
implicit val flattenList = new Flatten[List] {
def flatten[S](list: List[Option[S]]) = list.collect { case Some(s) => s }
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。