I am a Scala novice so forgive me if this is a stupid question, but here goes...
Imagine I wish to create an extended Map type that includes additional methods. I can see a few ways to do this. The first would be with composition:
class Path[V](val m: Map[V, Int]) {
// Define my methods
}
Another would be via inheritance, e.g.
class Path[V] extends Map[V, Int] {
// Define my methods
}
Finally, I've also considered the "trait" route, e.g.
trait Path[V] extends Map[V, Int] {
// Define my methods
}
Composition is a bit awkward because you are constantly having to reference the thing inside. Inheritance is a fairly natural but there is a wrinkle for me (more in a sec). Traits seems like a really elegant way to do this and using the "with" construct it is really nice but it also has an issue for me.
The wrinkle I'm running into is with methods like ++. They return a new map. So let's say the "my method" referred to above wishes to add something to the map (just an example, I know the map already has this), e.g.
trait Path[V] extends Map[V,Int] {
def addOne(v: V, i: Int): Path[V] = this + (v -> i)
}
This generates an error because the return type is not Path[V]. Now I know I can use "with" on a new instance to add the Path[V] trait. But I don't control the construction of the new map here. Is there any way to add the Path[V] trait? I thought about creating a new immutable map that was pre-populated and then tagging on a "with Path[V]", but there is no such constructor I can use to create the pre-populated map.
I suspect (although I haven't confirmed it) that I would have a similar issue using inheritance. I could add a new method to add a new entry to the map, but I would not get back a "Path[V]" which is what I want. The compositional approach seems to be the only way to go here.
I hope this is clear. Comments?