11

I'd like to initialize a scala BitSet to contain the integers from 1 to N. The following will work, but I'm looking for a better solution:

var s = BitSet.empty ++ (1 to n)

I was hoping that I could do something like this:

var s:BitSet = (1 to n).toSet

...but that results in an error:

error: polymorphic expression cannot be instantiated to expected type;
  found   : [B >: Int]scala.collection.immutable.Set[B]
  required: scala.collection.immutable.BitSet

Am I missing something obvious?

Mike
  • 1,539
  • 10
  • 12
  • 1
    I like the first solution. It's pretty impressive how it works underneath too. –  Jun 16 '11 at 04:22

2 Answers2

13

Thats what breakOut is for:

val s: BitSet = (1 to n).map(identity)(breakOut)

See this question to understand the inner working of breakOut.

Another solution is to use the constructor of BitSet:

val s = BitSet((1 to n): _*)

the : _* tells the compiler that you want to use the Range as repeated parameters.

Because breakOut looks ugly you can use the pimp-my-library pattern to produce nicer looking code (as described here):

val s = (1 to n).to[BitSet]
Community
  • 1
  • 1
kiritsuku
  • 52,967
  • 18
  • 114
  • 136
3

Digging into the Scala source code, the definition of toBitSet is in TraversibleOnce.scala:

/** Converts this $coll to a set.
 *  $willNotTerminateInf
 *  @return      a set containing all elements of this $coll.
 */
def toSet[B >: A]: immutable.Set[B] = immutable.Set() ++ self

So, interestingly enough, the Scala implementation of toSet is basically just doing your first solution behind the scenes in the case of a plain Set. If you really would strongly prefer the second syntax you suggested for the case of a BitSet, then you could roll your own with an implicit type conversion:

class BitSetConvertible(t: TraversableOnce[Int]) {
  def toBitSet = BitSet.empty ++ t
}

implicit def asBitSetConvertible(t: TraversableOnce[Int]) = new BitSetConvertible(t)

With that in place, you can now make statements like:

val s = 1 to 10 toBitSet
Chris Nauroth
  • 9,614
  • 1
  • 35
  • 39