Reputation: 181
Let's assume that we have the next two Enumerations:
object EnumX extends Enumeration {
val val1 = Value
val val2 = Value
}
object EnumY extends Enumeration {
val valA = Value
val valB = Value
}
These enumerations have similar business value and can't be changed. For some reason I'd like to have "new" type (let's name it MixedEnumXY) which can accept enum values from EnumX and EnumY:
E.g.
val e1: MixedEnumXY = EnumX.val1
val e2: MixedEnumXY = EnumY.valA
Is it possible to implement this in Scala?
Upvotes: 3
Views: 82
Reputation: 181
So, I came up with the next DRAFT solution
object EnumX extends Enumeration {
val val1 = Value
val val2 = Value
}
object EnumY extends Enumeration {
val valA = Value
val valB = Value
}
sealed trait MixedEnum {
def reason: Enumeration#Value
override def toString: String = reason.toString
}
case class EnumXMix(reason: EnumX.Value) extends MixedEnum
case class EnumYMix(reason: EnumY.Value) extends MixedEnum
object MixedEnum {
implicit def EnumX2MixedEnum(value: EnumX.Value) = EnumXMix(value)
implicit def EnumY2MixedEnum(value: EnumY.Value) = EnumYMix(value)
}
Now, you can use it the next way:
import MixedEnum._
val enumValue1: MixedEnum = EnumX.val1
val enumValue2: MixedEnum = EnumY.valA
val enumSeq: Seq[MixedEnum] = Seq(EnumX.val1, EnumY.valA)
println(enumValue1)
println(enumValue2)
println(enumSeq)
Output:
val1
valA
List(val1, valA)
Upvotes: 1
Reputation: 22595
Maybe you can use sealed case classes?
sealed trait XY
sealed trait X extends XY
sealed trait Y extends XY
object EnumX {
case object Val1 extends X
case object Val2 extends X
}
object EnumY {
case object ValA extends Y
case object ValB extends Y
}
val e1: XY = EnumX.Val1
val e2: XY = EnumY.ValA
Upvotes: 2
Reputation: 23788
What you want seems hacky to me so you probably should be OK with a hacky solution that relies on implicit conversions:
object EnumX extends Enumeration {
val val1 = Value
val val2 = Value
}
object EnumY extends Enumeration {
val valA = Value
val valB = Value
}
import scala.languageFeature.implicitConversions
object MixedEnumXY extends Enumeration {
val val1 = Value
val val2 = Value
val valA = Value
val valB = Value
implicit def fromEnumX(ex: EnumX.Value): MixedEnumXY.Value = ex match {
case EnumX.val1 => val1
case EnumX.val2 => val2
}
implicit def fromEnumY(ey: EnumY.Value): MixedEnumXY.Value = ey match {
case EnumY.valA => valA
case EnumY.valB => valB
}
}
def test(): Unit = {
val e1: MixedEnumXY.Value = EnumX.val1
val e2: MixedEnumXY.Value = EnumY.valA
}
The other obvious choice would be to use Either or create a similar custom class with your additional logic.
Upvotes: 1