I would like to derive a version of a Scala built-in collection that expands on the functionality for a particular generic type e.g.,
import scala.collection
Are you sure you really need to extend Scala collection? To make the code above work you can do this:
class Tuple2Set[T1,T2](set: Set[(T1, T2)]) {
def left = set map ( _._1 )
def right = set map ( _._2 )
}
implicit def toTuple2Set[T1, T2](set: Set[(T1, T2)]) = new Tuple2Set(set)
Set[(String, String)]() + (("x","y")) left
In this case Tuple2Set
is just the wrapper for any other Set
implementations. This means you are not limited to HashSet
anymore and your methods left
and right
will be available on any other implementations as well (like TreeSet).
I think in most cases wrapping or composition+delegation works much better than inheritance (and causes less problems).
As Kevin Wright said, +
operation will return back HashSet
. Type class CanBuildFrom
is used to build new collections during operations like map
. So if you want +
to return Tuple2Set
instead of HashSet
you should implement CanBuildFrom
and make it implicitly available in companion object like this:
object Tuple2Set {
implicit def canBuildFrom[T1, T2] =
new CanBuildFrom[Tuple2Set[T1, T2], (T1, T2), Tuple2Set[T1, T2]] {...}
}
The reason your example doesn't work is that the return type of the +
operation is a HashSet
and not a Tuple2Set
.
You'll have much more luck using the "pimp my library" pattern instead of inheritance.
The general answer to your question is a bit too involved for a response here. But it has been written up in some web pages.
The same material with more context is also in the 2nd edition of our book, Programming in Scala, Artima Press.