As suggested by Erik Engbrecht, I moved this topic from Scala-Debate
to this group. Here is the original message:
--------------
I think the new Scala Collection Framework could be a good reason to
discuss about additional data structures. I'm especially missing
MultiSet (a.k.a Bag), MultiMap and BidiMap. Of course it's easy to
come up with own implementations based on the existing classes (and
I'm pretty sure there are already some of these around), however I
think it is important that these classes fit into the new framework
structure.
What I want to discuss here is:
- Should these classes be part of the Scala distribution? If not, what
would be an approriate place?
- How should the interfaces look like, given the structure and the
limitations of the new framework?
What do you think?
--------------
I have already an ugly, but mostly working immutable proof-of-concept
implementation of MultiSet, using internally an immutable HashMap (the
Builder part makes still problems). However I'd prefer to start over
with a better, accepted interface design rather than bending the
existing mess in shape.
Cheers,
Daniel
Good idea.
I think discussion around these additional data structures would be
very appropriate here. If you have code that you'd like to share then
let me know and I'll set up a repository for it on the Scala Incubator
github account.
Cheers,
Miles
--
Miles Sabin
tel: +44 (0)7813 944 528
skype: milessabin
http://www.chuusai.com/
http://twitter.com/milessabin
Instead of going crazy with MultiSet, I tried to solve an easier
problem, an immutable bidirectional Map. I think a separate collection
type for bidirectional maps would be quite stupid, so I extended Map.
I'm not really happy with the + method, maybe you can give me a hint
how to deal with the variance here.
The file is quite short, so I hope it's fine to include it directly:
===========================
package scala.collection.immutable
class BidiMap[A, B] private(private wrapped: Map[A, B],
private inverse: Map[B, A]) extends Map[A,
B]{
self => if (wrapped.size != inverse.size)
throw new IllegalArgumentException("Duplicate values are not
permitted.")
lazy val inverseMap:BidiMap[B, A] = new BidiMap[B, A](inverse,
wrapped) {
override lazy val inverseMap = self
}
def inverseIterator: Iterator[(B, A)] = inverseMap.iterator
override def get(key: A): Option[B] = wrapped.get(key)
override def iterator: Iterator[(A, B)] = wrapped.iterator
override def + [B1 >: B] (kv: (A, B1)): BidiMap[A, B1] = {
val inverseWidened: Map[B1, A] = inverse match {
case _: Map[B1, A] => inverse
case _ => Map[B1, A]() ++ inverse
}
new BidiMap[A, B1](
inverseWidened.get(kv._2).map(wrapped - _).getOrElse(wrapped) +
kv,
inverseWidened + kv.swap)
}
override def - (key: A): BidiMap[A, B] = wrapped.get(key).map(value
=>
new BidiMap(wrapped - key, inverse - value)).getOrElse(this)
override def empty: BidiMap[A, B] = BidiMap[A, B]()
override def size = wrapped.size
}
object BidiMap {
def apply[K, V](): BidiMap[K, V] = new BidiMap(Map[K, V](), Map[V, K]
())
def apply[K, V](ws : (K, V)*): BidiMap[K, V] = BidiMap(Map[K,V]() ++
ws)
def apply[K, V](wrapped: Map[K,V]): BidiMap[K, V] =
new BidiMap(wrapped, wrapped.map(tuple => tuple.swap))
}
===========================
What do you think, could this be useful?
Cheers,
Daniel
On 26 Dez., 15:47, Miles Sabin <mi...@milessabin.com> wrote:
--
Daniel C. Sobral
I travel to the future all the time.