Something like this:
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) }
}
Kinda works ... except that val foo: Seq[(Int, String)] = Seq(("foo",1)).swap does not compile, because swap returns Iterable rather than a Seq.
How do I fix it? There used to be breakOut in 2.12 that was using some magic (that I never quite understood tbh) to do this kind of thing ... but now I need a Factory ...
Tried adding it as an implicit param:
def swap(implicit f: Factory[(B,A),C]) = c.map { case (a,b) => (b,a) }.to(f) }
This compiles with the right type, but I can't use it, because I don't have that implicit in scope at the call site (even swap(Seq) does't work for some reason, even though swap.to(Seq) does (in the first version, without implicit factory) ...
Can someone please set me straight here? There must be a way to accomplish what I want here, but I can't figure out the right incantation :(
What works for me is modifying the implicit you are fetching:
see Scastie
The reason for the verbosity is that ask for
[A, C[_]]and makeC[A]out of it approach which was used prior to 2.13 doesn't work if you want to do e.g.(You can check that in 2.12 when you use
.to(Map)(e.g with scala-collection-compat) you'll end up with a Map... upcasted toIterable[(K, V)]precisely because.tointerface operates on[A, Coll[_]]and to be able to shoveMapfactory there, it has to upcast it toIterablefactory.)In other words the verbosity added by by 2.13 allows
Factoryto be used in cases likeseq.map(a => a -> a.toString).to(Map)which eliminated the need forCanBuildFromand separate syntax for.to[Coll]and.toMap.