Reputation: 18177
I have a test which fails intermittently because of ordering issues when I iterate over the values in a Map
.
Scala helpfully provides a ListMap
which makes the tests stable, at the expense of performance. So I abstracted the ImmutableMapFactory
as a val and use it in my code.
class C {
val immutableMapFactory = scala.collection.immutable.Map
def func = {
...
immutableMapFactory(pairs :_*)
}
}
Now my plan was to extend C and override immutableMapFactory
for tests
class TestableC extends C {
override val immutableMapFactory = scala.collection.immutable.ListMap
}
Unsurprising this fails as ListMap
does not have the same type as Map
. How should I specify the type of the val (or a def) so that I can use the factory wherever I need to create a Map?
Upvotes: 1
Views: 841
Reputation: 49705
Your problem is in this line:
val immutableMapFactory = scala.collection.immutable.Map
This makes immutableMapFactory
equal to the singleton object Map
. ListMap
(the singleton) is not a subclass of Map
(the singleton), so the subsequent override fails.
If you instead take the apply
method from Map
, and partially apply it to form a first class function (of type (A, B)* => immutable.Map[A,B]
) then the technique can be made to work:
import collection.immutable
class Bip {
def fac[A,B] = immutable.Map.apply[A,B] _
}
class Bop extends Bip {
override def fac[A,B] = immutable.ListMap.apply[A,B] _
}
Upvotes: 2
Reputation: 297305
Two possible ways. First, using def
and functions, which I think is a better abstraction.
class C {
def immutableMapFactory[A,B]: ((A,B)*) => Map[A,B] = scala.collection.immutable.Map.apply _
}
class TestableC extends C {
override def immutableMapFactory[A,B] = scala.collection.immutable.ListMap.apply _
}
Second, using val
, and structural types:
class C {
val immutableMapFactory: { def apply[A,B](t: (A,B)*): Map[A,B] } = scala.collection.immutable.Map
}
class TestableC extends C {
override val immutableMapFactory: { def apply[A,B](t: (A,B)*): Map[A,B] } = scala.collection.immutable.ListMap
}
Upvotes: 3