Hi everyone,
I’m working with Scala 3 and attempting to implement a compile-time feature that maps an enum’s total number of members to the smallest appropriate primitive numeric type (or immutable.BitSet as a fallback) using Match Types.
My intended workflow is:
-
First, calculate the enum’s member count at compile time via the
SizeOfinline method (usingMirror.SumOffor compile-time reflection). -
Then, use a Match Type (
BitOption[E]) to map theSizeOfresult toByte/Short/Int/Long/BitSetbased on numeric ranges.
However, when I compile the code, I encounter the error: Not found: type SizeOf — the compiler seems unable to resolve SizeOf as a type within the BitOption Match Type definition.
Here’s my complete, reproducible code:
import scala.collection.immutable
import scala.deriving.Mirror
import scala.compiletime.ops.int.*
import scala.compiletime.*
import scala.reflect.Enum
object Main {
enum Language:
case Java, Scala, Kotlin, Groovy, Clojure
// Compile-time inline method to get enum member count
transparent inline def SizeOf[E <: Enum](using m: Mirror.SumOf[E]): Int =
constValue[Tuple.Size[m.MirroredElemTypes]]
// Match Type to map enum size to corresponding numeric type
type BitOption[E <: Enum] = SizeOf[E] match
case 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 => Byte
case 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 => Short
case 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 | 32 =>
Int
case 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 |
47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 |
61 | 62 | 63 | 64 =>
Long
case _ => immutable.BitSet
def main(args: Array[String]): Unit = {
val usedLanguage: BitOption[Language] = 0
assert(usedLanguage.isInstanceOf[Byte]) // Expect to pass (Language has 5 members)
}
}
My specific questions:
-
Why am I getting the “Not found: type SizeOf” error? I defined
SizeOfas a transparent inline method — is there a misunderstanding here about the difference between inline methods and types in Scala 3, especially when using them within Match Types? -
How can I correctly reference the compile-time value of
SizeOf[E]within theBitOptionMatch Type to make the compiler resolve it properly? -
Additionally, is there a more idiomatic way to express numeric ranges in Scala 3 Match Types (e.g.,
1 to 8instead of listing every number) to avoid verbosity and typos?
Any guidance, corrections, or working examples would be greatly appreciated. Thank you in advance!