如何在scala 2.13中正确使用集合工厂?

问题描述 投票:0回答:1

类似这样的:

implicit class PairOps[A, B, C[X] <: Iterable[X]](val c: C[(A,B)]) extends AnyVal {
   def swap = c.map { case (a, b) => (b, a) } 
}

有点有效...除了

val foo: Seq[(Int, String)]  = Seq(("foo",1)).swap
无法编译,因为
swap
返回
Iterable
而不是
Seq

如何解决? 2.12 中曾经有

breakOut
正在使用一些魔法(说实话,我一直不太理解)来做这种事情......但现在我需要一个
Factory
...

尝试将其添加为隐式参数:

   def swap(implicit f: Factory[(B,A),C]) = c.map { case (a,b) => (b,a) }.to(f) }

这可以使用正确的类型进行编译,但我无法使用它,因为我在调用站点的范围内没有隐含的范围(即使

swap(Seq)
出于某种原因也不起作用,尽管
swap.to(Seq)
确实(在第一个版本中,没有隐式工厂)...

有人可以帮我指点一下吗?一定有一种方法可以实现我在这里想要的,但我无法找出正确的咒语:(

scala extension-methods implicit scala-collections
1个回答
0
投票

我花了一些时间摆弄,说实话,我不是100%确定为什么这有效(如果有人提出解释,你可能应该接受他们的答案),但看起来这得到了工作完成:

implicit class PairOps[A, B, C[X]](val c: C[(A, B)]) extends AnyVal {
  def swap(implicit ev: C[(A, B)] <:< collection.IterableOnceOps[(A, B), C, _]): C[(B, A)] =
    c.map(_.swap)
}

返回的类型是由

PairOps
包装的集合之一。您可以在 Scastie 上使用此代码。

© www.soinside.com 2019 - 2024. All rights reserved.