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
andResult.Failure
. You would be able to use conventional dynamic type checking withis
, 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
?
- like a tuple?