Referring to a previous answer of mine on stackoverflow
The core of the complexity is illustrated in just one method:
implicit def traversableToFilterOps[CC[X] <: Traversable[X], T]
(xs: CC[T])(implicit witness: CC[T] <:< TraversableLike[T,CC[T]]) =
new MoreFilterOperations[CC[T], T](xs)
With two questions:
Is there any way to give the compiler a hint that
Map
meets the signatureCC[X] <: Traversable[X]
? I would expect it to match as aTraversable[Tuple2[_,_]]
but this doesn't happen. In the end, I had to write a second method takingCC[KX,VX] <: Map[KX,VX]
, but that feels redundantwitness: CC[T] <:< TraversableLike[T,CC[T]]
also seems redundant given the first type parameter, my gut feeling is that this is enforced by the type ofTraversable
and must always hold true for any possible subclass or value ofX
, so there should be no reason to explicitly require it as a witness.
If I test this using an existential type in the REPL, then the compiler seems to agree with me:
scala> implicitly[Traversable[X] <:< TraversableLike[X,Traversable[X]] forSome { type X }]
res8: <:<[Traversable[X],scala.collection.TraversableLike[X,Traversable[X]]] forSome { type X } = <function1>
Is there therefore any way to do away with the boilerplate?