[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