AlexanderM
(Alexander Momchilov)
17
I think this is certainly a problem worth solving, and this looks like a great simple solution.
I've thought about this before, and had a different approach in mind. I don't know if it's better or worse, but I'll toss it out there:
I thought it would be nice if each case of an enum also produced a new corresponding type, as a subtype of the enum. Here are some of the features this allows:
-
Detecting a case ignoring any associated values
(Akin to is case .success(_))
Take Result for an example. It might have two subtype auto-generated: Result.Success and Result.Failure. You would be able to use conventional dynamic type checking with is, like:
if result is Result.Success { ... }
-
Accessing associated values
This subtype can act like a tuple, with one named property per associated value of the enum case. This could be used in if statements like with any other value:
if let success = result as Result.Success, success.value == 123 { ... }
-
Extracting functions that operate on a single case
Suppose you had a switch over an enum value, with long case bodies. Today, these cases are hard to extract, because you lose the specific case information:
switch someEnum {
case a: handleCaseA(a) // case information is lost in this call, going back to SomeEnum
...
}
func handleCaseA(_ a: SomeEnum) {
guard case .a(payload) = a else { return } // Need to manually narrow down the type again
print(payload)
// some long body
}
If each case got its own type, this would have a very nice solution:
switch someEnum {
case a: handleCaseA(a) // case information is lost in this call, going back to SomeEnum
...
}
func handleCaseA(_ a: SomeEnum.A) { // Only a "SomeEnum.a" can make it here
// Only a `SomeEnum.a` can make it here, no checking needed
print(a.payload)
// some long body
}
Some loose ends:
- What would these subtypes be called?
- ...and how do we keep those names from colliding with type param names of generic enums?
- How do you access unnamed associated values?
- like a tuple?
.0, .1, .2, ...
- if there's only one, perhaps some standard name, like
.value?
2 Likes