2

I was able to loop my enumerations when I did it like:

object Colors extends Enumeration {
  type Colors = Value
  val Red, Green, Blue, Yellow = Value
}

for(e <- Colors.values) { ... }

So it was easy for me to create a dropdown list etc.

Now my enumeration stores bit values like:

object BitMask1 extends Enumeration {
  val none = math.pow(2,0).toLong
  val Green = math.pow(2,2).toLong
  val Yellow = math.pow(2,3).toLong
  val Black = math.pow(2,4).toLong
  // etc
}

How could I possible loop through these values?

Blankman
  • 259,732
  • 324
  • 769
  • 1,199
  • You could add them manually to a collection field inside this singleton, if this is desirable (not many values, you may alter the source code). Or am I missing something here? – mucaho Feb 10 '15 at 00:29

2 Answers2

4

You can't, since you're not invoking the Value method of Enumeration, hence no enumeration cases are being created.

Scala Enumeration is known to be broken, can I suggest an ADT approach instead?

sealed trait BitMask { def repr: Long }
object BitMask {
  case object None extends BitMask { val repr = math.pow(2, 0).toLong }
  case object Green extends BitMask { val repr = math.pow(2, 2).toLong }
  case object Yellow extends BitMask { val repr = math.pow(2, 3).toLong }
  case object Black extends BitMask { val repr = math.pow(2, 4).toLong }
  // etc
}

and then you can use a macro to enumerate the values.

Community
  • 1
  • 1
Gabriele Petronella
  • 106,943
  • 21
  • 217
  • 235
  • ADT stands for [Algebraic Data Type](http://en.wikipedia.org/wiki/Algebraic_data_type). You can read more about this approach applied to scala enumerations here: http://underscore.io/blog/posts/2014/09/03/enumerations.html – Gabriele Petronella Feb 09 '15 at 23:53
  • Some people are vocal about hating Enumeration, but "known to be broken" only means "software has bugs." It does what it was intended to do, and covers other use cases too, which is more than most software achieves. – som-snytt Feb 10 '15 at 21:40
  • @som-snytt, I don't agree. Bugs are incorrect implementations. `Enumeration` is simply a badly designed API, implemented just fine (as far as I can tell). Then of course nothing prevents you from hammering a nail with a screwdriver. – Gabriele Petronella Feb 10 '15 at 22:16
  • It's the poster child of path dependent types. That's also the implementation bug. But I'd challenge you to find anything objectionable in the API described here: http://www.artima.com/pins1ed/abstract-members.html#20.8 granted that it's not an API that slices and dices. If it were bad API, Odersky would not have defended it for so long. Not that I want to become the Great Defender... I sympathize with people who want more power that just works, maybe w/o learning new vocab, syntax and macros. – som-snytt Feb 10 '15 at 23:13
0

There are different ways Enumeration can serve your needs.

Here is one:

scala> object Colors extends Enumeration { val None, Blue, Green, Yellow = Value }
defined object Colors

scala> import Colors._
import Colors._

scala> Blue.id
res0: Int = 1

scala> Yellow.id
res1: Int = 3

scala> object Colors extends Enumeration {
     |   val None, Blue, Green, Yellow = Value
     |   implicit class `color mask`(val v: Value) extends AnyVal {
     |     def mask = 1L << v.id
     |   }
     |   implicit class `colors mask`(val vs: ValueSet) extends AnyVal {
     |     def mask = vs.toBitMask(0)
     |   }
     | }
defined object Colors

scala> import Colors._
import Colors._

scala> Blue.mask
res2: Long = 2

scala> Yellow.mask
res3: Long = 8

scala> (Blue + Yellow).mask
res4: Long = 10

scala> for (v <- Colors.values) yield v.mask
res5: scala.collection.immutable.SortedSet[Long] = TreeSet(1, 2, 4, 8)

Other ideas.

Community
  • 1
  • 1
som-snytt
  • 39,429
  • 2
  • 47
  • 129