大概是这样的:
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
,它使用了一些魔法(我从来没有完全理解tbh)来做这种事情。但现在我需要一个Factory
...
已尝试将其作为隐式参数添加:
def swap(implicit f: Factory[(B,A),C]) = c.map { case (a,b) => (b,a) }.to(f) }
这可以用正确的类型编译,但是我不能使用它,因为我在调用站点的作用域中没有隐式类型(即使swap(Seq)
由于某种原因也不能工作,尽管swap.to(Seq)
可以(在第一个版本中,没有隐式工厂)。
有没有人能帮我把话说清楚?一定有一种方法可以达到我的目的,但我想不出正确的咒语:(
2条答案
按热度按时间gt0wga4j1#
对我有用的是修改你正在获取的隐式:
参见Scastie
冗长的原因是,如果你想做,那么在2.13之前使用的 * 请求
[A, C[_]]
并从中生成C[A]
* 的方法就不起作用了。(You可以检查一下,在2.12中,当你使用
.to(Map)
(例如,使用scala-collection-compat)时,你最终会得到一个Map.上推到Iterable[(K, V)]
正是因为.to
接口在[A, Coll[_]]
上运行,并且为了能够将Map
工厂推到那里,它必须上推到Iterable
工厂。)换句话说,在2.13中增加的versity允许
Factory
用于像seq.map(a => a -> a.toString).to(Map)
这样的情况,这消除了对CanBuildFrom
的需要,并为.to[Coll]
和.toMap
提供了单独的语法。ekqde3dh2#
花了我一点时间,老实说,我不是100%确定 * 为什么 * 这是有效的(如果有人沿着解释,你可能应该接受他们的答案),但看起来这可以完成工作:
返回的类型是由
PairOps
Package 的集合的类型。你可以使用这个代码here on Scastie。