[swift-evolution] Treating an Enum's Cases as Its Subtypes

Haravikk swift-evolution at haravikk.me
Mon Feb 20 05:23:11 CST 2017


> On 20 Feb 2017, at 06:40, Niels Andriesse via swift-evolution <swift-evolution at swift.org> wrote:
> 
> I'd like to discuss the possibility of treating the cases of a given enum as if they are subtypes of that enum. This seems like a natural thing to do because enum cases (especially when they have associated values) effectively define a closed set of subtypes.
> 
> Doing so would allow for constructions such as the following:
> 
> enum Foo {
>   case a(name: String)
> }
> 
> func isA(foo: Foo) -> Bool {
>   // The old way:
>   if case .a = foo { return true }
>   return false
>   // The new way:
>   return foo is .a
> }
> 
> func printNameIfFooIsA(foo: Foo) -> Bool {
>   // The old way:
>   if case let .a(name) = foo {
>     print(name)
>   }
>   // The new way (1):
>   if let a = foo as? .a {
>     print(a.name <http://a.name/>)
>   }
>   // The new way (2):
>   if let name = (foo as? .a)?.name {
>     print(name)
>   }
> }
> 
> Treating an enum's cases as its subtypes would make enums easier to work with because handling them would be syntactically the same as handling other types.
> 
> The pattern matching capabilities of enums wouldn't be affected by this proposal.
> 
> Multiple other proposals have already attempted to simplify enum handling (they have particularly focused on getting rid of "if case" and adding the ability to treat enum case tests as expressions), but none of the solutions presented in those proposals have worked out so far.
> 
> I believe that this could be the right solution to multiple enum-related problems that have been brought up repeatedly.

I really like the simplification of is/as here, since the leading dot should be clear enough and is consistent with other usages of enums.

Presumably this would apply even further though? For example, could I do:

	func myMethod(_ something:Foo.a) -> Foo.a { … }

i.e- take and return only instances of Foo.a?

It should then also be possible for me to do:

	let a:Foo = myMethod(Foo.a("test"))

In other words, Foo.a is a valid instance of Foo (but not vice versa without casting first)?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170220/20d31718/attachment.html>


More information about the swift-evolution mailing list