I am writing a class which extends Scala's immutable map with some custom constructor logic. As a simple example, say I want a map of integers to strings that is initialized as 1 -> "one", 2 -> "two". In the REPL I can write the following.
scala> import collection.immutable.HashMap import collection.immutable.HashMap scala> HashMap[Int, String](1->"one", 2->"two") res0: scala.collection.immutable.HashMap[Int,String] = Map(1 -> one, 2 -> two) In my program I'd like to use the same constructor call, but I get a "too many arguments for constructor" error when I try to put it in the class definition line.
scala> class MyMap extends HashMap[Int, String](1->"1", 2->"2") <console>:8: error: too many arguments for constructor HashMap: ()scala.collection.immutable.HashMap[Int,String] class MyMap extends HashMap[Int, String](1->"1", 2->"2") ^ Given that the way to call superclass constructors is in the class definition, I figured that any expression that creates a HashMap in the REPL should also work in the definition, but there's some subtlety I'm missing here.
(I think extending the concrete class HashMap instead of a trait is the right thing to do here because I want to use the default map implementation. Extending HashMap is what I'd do in Java, but I'm not 100% certain that extending concrete collection classes is the most Scalaesque way to operate.)
Because I want MyMap to be immutable, I need to specify the initial values at constructor time. I can trying doing the initialization inside the apply function of the companion object like so:
class MyMap extends HashMap[Int, String] object MyMap { def apply() = new MyMap ++ List(1 -> "one", 2 -> "two") } But MyMap() returns an immutable map instead of a MyMap.
What is the correct way to initialize MyMap?
This link about implementing Map with concrete types is relevant.