enum Draw(val char: Char):
case Rock extends Draw('r')
case Paper extends Draw('p')
case Scissors extends Draw('s')
// ... more consts like "case Well ..."
(The extends values are defined to read draws from text files.)
Now I need a “constructor” Char => Draw. My first implementation is:
This looks a bit convoluted, so I was thinking, maybe the companion object to Draw contains some helper making this definition easier? This must be a common situation…
Personally I would make the code return an Option[Draw] since the char may not be one of the cases and defaulting to an arbitrary one feels wrong.
Also, not sure what is convoluted about that code, is literally just a one-liner and is very clear on its intent.
Anyways no, AFAIK, there is no other way using plain enum
You may check other libraries like enumeratum or enum-extensions.
Yeah, totally as Thanh and Seth said, that is the natural place.
Also, I would name it fromValue or fromChar.
So you are thinking of a very specific kind of enum; usually called value enum. If that was the only kind of enum the language supported, then sure this fromValue should be defined.
However, enum is very much general and supports a lot of ADTs, thus assuming all cases will have a single value and it will be a constant is not viable.
Thus, you rather have generic tools to build your desired behavior.
IMHO, the language should have two constructs, enum and adt, and enum should be very close to what Enumeratum provides. But that boat already sailed.
That is actually a very common idiom in the language.
If the method does nothing fancy and returns a plain value of the companion type, then we usually use apply.
But, if the method performs some validations and what not and returns something like Option[Foo] or Either[Error, Foo] then fromX is a common name.