SkyWalker
SkyWalker

Reputation: 14307

Scala: How to define an enum with extra attributes?

I have a use-case where I need to define a new enum type LongShort but I need it in a way to also carry the sign so it can be directly used in mathematical expressions e.g.

object LongShortType extends Enumeration {
    type Type = Value
    val Long = Value(+1)
    val Short = Value(-1)
}

I'd then like to use it like this:

val longShort = LongShortType.Short 
val numberOfContracts: Int = 10
val vanillaOptionNotional: Double = longShort*numberOfContracts

but this leads to compiler error cannot resolve symbol * ... is there a way to extract the value of the enum? Or am I not understanding how enum types work?

Upvotes: 1

Views: 579

Answers (2)

SkyWalker
SkyWalker

Reputation: 14307

OK I worked out a solution to accomplish what I wanted without any compromisse and by that I mean that this solution has all the advantages of using Scala enum e.g. the withName and still allows me to define extra features on it:

object LongShortType extends Enumeration {
  type Type = LongShortVal
  val Long = Value("Long", +1)
  val Short = Value("Short", -1)
  case class LongShortVal(name: String, sign: Int) extends Val(nextId, name)
  protected final def Value(name: String, sign: Int) = new LongShortVal(name, sign)
}

and now can do:

val longShort = LongShortType.Short 
val numberOfContracts: Int = 10
val vanillaOptionNotional: Double = longShort.sign*numberOfContracts

and can also do:

val longShort = LongShort.withName("Long") // returns LongShort.Long

Upvotes: 1

Yuval Itzchakov
Yuval Itzchakov

Reputation: 149538

The type of LongShortType.Short isn't Int, it's Value. You can either extract the underlying id of the value:

val longShort = LongShortType.Short.id

Which is a little ugly. Or you could not use an enum type at all:

object LongShortType {
  val Long = 1
  val Short = -1 
}

And then your equation would work as is.

Upvotes: 1

Related Questions