Home > OS >  Scala, case object with productIterator-able fields?
Scala, case object with productIterator-able fields?

Time:07-30

I'd like to use a case object as a typo-safe way to access members of a finite set, however this set also needs to be passed to an API as a proper Set.

I figured that I could do something like:

case object KnownFruits(
    banana     = "banana"
    apple      = "apple"
    watermelon = "watermelon")

val knownFruitsSet = KnownFruits.productIterator.toSet.asInstanceOf[Set[String]]

tragically, this doesn't even compile. declaring the values in the body of KnownFruits also doesn't work, presumably because productIterator only iterates over the constructor parameters of case classes/objects.

I imagine case objects can't be given parameters because there is a more desirable way of achieving this kind of use-case?

CodePudding user response:

If you are using Scala 3 then all you need to use is an enum, like this:

enum Fruits:
  case Banana, Apple, Watermelon
object Fruits:
  val names: Set[String] =
    values.map(_.toString).toSet
end Fruits

See the code running here.

CodePudding user response:

I recommend the KISS approach.

case object KnownFruits {
  val banana     = "banana"
  val apple      = "apple"
  val watermelon = "watermelon"

  def toSet: Set[String] =
    Set(banana, apple, watermelon)

}

A bit more typing, yes. But far less "magic" and very obvious what it's doing at a glance.

val knownFruitsSet = KnownFruits.toSet
  • Related