[swift-evolution] [Pitch] Enum with generic cases
Joshua Alvarado
alvaradojoshua0 at gmail.com
Mon Apr 24 15:34:33 CDT 2017
Well in your case thing one and thing two will be the same type as you are
using the same T generic type on both.
To achieve your case you can do an extension on the enum and use two
different generics:
enum Thing {
case thingOne<T>(T)
case thingTwo<U>(U)
}
extension Thing where T == String, U == Int {
func handle(thing: Thing) {
switch thing {
case thingOne(let s):
// s is type String
case thingTwo(let i):
// i is an Int
}
}
}
This can actually be achieved in Swift 3.1, you can run this in a
playground.
enum Foo<T, U> {
case bar(obj: T)
case baz(obj: U)
func handle() {
switch self {
case .bar(obj: let x):
break
case .baz(obj: let y):
break
}
}
}
extension Foo where T == String, U == Int {
func handle() {
switch self {
case .bar(obj: let str):
print(str)
case .baz(obj: let aNum):
print(aNum)
}
}
}
let foo = Foo<String, Int>.baz(obj: 1)
foo.handle() // prints 1
On Mon, Apr 24, 2017 at 2:15 PM, Kevin Nattinger <swift at nattinger.net>
wrote:
> This makes it more convenient to create them, sure, but how would you pass
> them around or extract the value in a type-safe manner?
>
> e.g. now I can write:
> enum Thing<T, U> {
> case thingOne(T)
> case thingTwo(U)
> }
>
> // How do I require thingOne<String> or thingTwo<Int>?
> func handle(thing: Thing<String, Int>) {
> switch thing {
> case .thingOne(let s): print("string \(s)")
> case .thingTwo(let i): print("int \(i)")
> }
> }
>
> With your proposed syntax:
>
> enum Thing {
> case thingOne<T>(T)
> case thingTwo<T>(T)
> }
>
> func handle(thing: Thing) {
> switch thing {
> case thingOne(let s):
> // What is the type of s?
> case thingTwo<Int>(let i):
> // is it even possible to write an exhaustive switch?
> }
> }
>
>
>
> On Apr 24, 2017, at 6:57 AM, Joshua Alvarado via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> Here is my pitch on adding generics to enum cases and not to the enum type
> itself. Let me know if you have an improvements or modifications lets open
> it to discussion thank you swiftys! :)Enum with generic cases
>
> - Proposal: SE-NNNN
> <https://github.com/lostatseajoshua/swift-evolution/blob/master/NNNN-enum-generic-cases.md>
> - Authors: Joshua Alvarado <https://github.com/alvaradojoshua0>
> - Review Manager: TBD
> - Status: PITCH
>
> *During the review process, add the following fields as needed:*
>
> - Decision Notes: Rationale
> <https://lists.swift.org/pipermail/swift-evolution/>, Additional
> Commentary <https://lists.swift.org/pipermail/swift-evolution/>
> - Bugs: SR-NNNN <https://bugs.swift.org/browse/SR-NNNN>, SR-MMMM
> <https://bugs.swift.org/browse/SR-MMMM>
> - Previous Revision: 1
> <https://github.com/apple/swift-evolution/blob/...commit-ID.../proposals/NNNN-filename.md>
> - Previous Proposal: SE-XXXX
> <https://github.com/lostatseajoshua/swift-evolution/blob/master/XXXX-filename.md>
>
>
> <https://github.com/lostatseajoshua/swift-evolution/tree/master#introduction>
> Introduction
>
> This proposal adds a change to the enumeration type that allows an enum
> case to cast a generic on its associated value.
>
> Swift-evolution thread: Discussion thread topic for that proposal
> <https://lists.swift.org/pipermail/swift-evolution/>
> <https://github.com/lostatseajoshua/swift-evolution/tree/master#motivation>
> Motivation
>
> Enums currently support generics, but they are added onto the type itself.
> This can cause adverse syntax when implementing generics for associated
> values to be stored along each case. The enum case holds the associated
> value (not the enum type itself) so should create its own value constraints.
>
> <https://github.com/lostatseajoshua/swift-evolution/tree/master#proposed-solution>Proposed
> solution
>
> The generic is to be casted on the case of the enum and not on the enum
> itself.
>
> <https://github.com/lostatseajoshua/swift-evolution/tree/master#detailed-design>Detailed
> design
>
> Current implementation:
>
> // enum with two generic typesenum Foo<T: Hashable, U: Collection> {
> case bar(obj: T)
> case baz(obj: U)
> }
> // U is to be casted but it is not even usedlet foo: Foo<String, [String]> = .bar(obj: "hash")
> // Creating an optional enum, the generics have to be casted without a value set// The casting is really not needed as the values should be casted not the enumvar foo1: Foo<String, [String]>?
> // Collections don’t look great eithervar foos = [Foo<String, [String]>]()
> foos.append(.bar(obj:"hash"))
>
> Proposed solution
>
> enum Foo {
> case bar<T: Hashable>(obj: T)
> case baz<U: Collection>(obj: U)
> }
> // generic type inferred on Tvar foo: Foo = .bar(obj: "hash")
> // doesn’t need to cast the generic on the optional enum// the associated value will hold the castvar foo1: Foo?
> // This also gives better syntax with collections of enums with associated typesvar foos = [Foo]()
> foos.append(.bar(obj: "hey")
>
>
> <https://github.com/lostatseajoshua/swift-evolution/tree/master#source-compatibility>Source
> compatibility
>
> This may cause subtle breaking changes for areas in code with generic enum
> cases. The compiler could help with the change by finding the associated
> generic and updating the case with the new syntax.
>
> <https://github.com/lostatseajoshua/swift-evolution/tree/master#alternatives-considered>Alternatives
> considered
>
> An alternative would be to extend the associatedtype keyword to the enum
> type.
>
> enum Foo {
> associatedtype T = Hashable
> case bar(obj: T)
> }
>
>
> Copy of proposal can be found here Swift proposal on github
> <https://github.com/lostatseajoshua/swift-evolution/blob/master/NNNN-enum-generic-cases.md>
>
> --
> Joshua Alvarado
> alvaradojoshua0 at gmail.com
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
--
Joshua Alvarado
alvaradojoshua0 at gmail.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170424/5dc15418/attachment.html>
More information about the swift-evolution
mailing list