I'm learning Scala 3, and I was intrigued by match types and literal types.
I'd like to write a function that takes one of a few literal types, and returns a particular type as a function of which literal type was passed in.
Here's a fairly minimal example of what I'm trying to do:
type TestMatchType[T] = T match
case "String1" => Int
case "String2" => String
def testMatchType[T](input: T): TestMatchType[T] =
input match
case "String1": "String1" => 1
case "String2": "String2" => "Two"
val string1Output: Int = testMatchType("String1")
In words:
- "I'd like to write a function,
testMatchType
, which takes an argument whose type is either the type literal"String1"
, or the type literal"String2"
. If an argument with type"String1"
is passed, the function should return anInt
. If an argument with type"String2"
is passed, the function should return aString
. If an argument is passed whose type is not one of these type literals, a compile-time error is produced."
However, when I try to compile the above code, I get the following error:
1 |val string1Output: Int = testMatchType("String1")
| ^^^^^^^^^^^^^^^^^^^^^^^^
| Found: TestMatchType[String]
| Required: Int
|
| Note: a match type could not be fully reduced:
|
| trying to reduce TestMatchType[String]
| failed since selector String
| does not match case ("String1" : String) => Int
| and cannot be shown to be disjoint from it either.
| Therefore, reduction cannot advance to the remaining case
|
| case ("String2" : String) => String
I'm trying to grok that error message. I'm struggling to understand the line "selector String does not match case ("String1" : String) => Int
". I would love some advice if there's a way to make this work.
Thank you!
You don't need to use
"foo": "foo"
, just use_: "foo"
.However, the error happens because
T
will not be inferred as a singleton type, so the return type will never beInt
orString
either, it'll remainTestMatchType[String]
. You'll either have to useT <: Singleton
or useinput.type
as an argument toTestMatchType
(I prefer the latter).Scastie