[swift-evolution] [Proposal] Using Union instead of Generic Enum to implement Optional

Cao Jiannan frogcjn at 163.com
Sun May 15 06:08:46 CDT 2016


This is the example implemented with generic and enum.

enum UnionOf3 <T,U,V>{
    case type0(T)
    case type1(U)
    case type2(V)
}

func input(value: UnionOf3<A,B,C>) {
    switch value {
    case let .type0(a):
        print(a)
    case let .type1(b):
        print(b)
    case let .type2(c):
        print(c)
    }
}

let a = A()
input(UnionOf3.type0(a))

For each different number N of types to get union, you should announce UnionOfN for each.
it is more complicated then the union solution. 

func input(value: (A | B | C)) {
    switch value {
    case a as A:
        print(a)
    case b as B:
        print(b)
    case let .type2(c):
        print(c)
    }
}

let a= A()
input(a)


And the most bad thing is,
compiler doesn’t know the type relation between generic union with original type,
 for example, the type relation between A and A | B and A | B | C.

compare:

enum UnionOf3 <T,U,V>{
    case type0(T)
    case type1(U)
    case type2(V)
}

let a = A()
let union: UnionOf3<A,B,C> = UnionOf3.type0(a) // You should wrap by yourself.

a == union // probably the compiler will refuse to compare.

sub-typing: 

var fn0: A->Void = {print($0)}
var fn1: UnionOf2<A,B>->Void = {print($0)}

fn0 = fn1 // This should be allowed. But will be rejected since using enum.

var fn2: UnionOf3<A,B,C>->Void = {print($0)}

fn0 = fn2 // This should be allowed. But will be rejected since using enum.
fn1 = fn2 // This should be allowed. But will be rejected since using enum.


---------------------------------------------------------------------------

If using union, this problem can be solved easily.

let a = A()
let union: (A|B|C) = a // Automatically wrap.

a == union // Yes

sub-typing: 

var fn0: A->Void = {print(v0)}
var fn1: (A|B)->Void = {print(v0)}

fn0 = fn1 // OK

var fn2: (A|B|C)->Void = {print($0)}

fn0 = fn2 // OK
fn1 = fn2 // OK


> 下面是被转发的邮件:
> 
> 发件人: Cao Jiannan via swift-evolution <swift-evolution at swift.org>
> 主题: [swift-evolution] Fwd: Union instead of Optional
> 日期: 2016年5月15日 GMT+8 18:34:44
> 收件人: Adrian Zubarev via swift-evolution <swift-evolution at swift.org>
> 回复-收件人: Cao Jiannan <frogcjn at 163.com>
> 
> for example, there is a method input union of 3 types: A, B, C,
> 
> This is the three class.
> 
> class A {}
> 
> class B {}
> 
> class C {}
> 
> This is how it implemented under Swift 2:
> 
> enum UnionABC {
>     case classA(A)
>     case classB(B)
>     case classC(C)
> }
> 
> func input(value: UnionABC) {
>     
> }
> 
> let a = A()
> let b = B()
> let c = C()
> input(UnionABC.classA(a))
> 
> 
> It needs announce all the cases and name each cases and cannot use class names as their case names.
> 
> what about using union? It is more easy and rational.
> 
> 
> func input(value: (A | B | C)) {
>     
> }
> 
> let a= A()
> input(a)
> 
> Or you can implement it with protocol and extension, but compiler will not know how many cases it should have.
> 
> 
> protocol UnionABC {
>     
> }
> 
> extension A: UnionABC {}
> extension B: UnionABC {}
> extension C: UnionABC {}
> 
> 
> func input(value: UnionABC) {
>     if value is A {
>         
>     } else if value is B {
>         
>     } else if value is C {
>         
>     } else {
>         // There are other cases? Compiler doesn't know
>     }
> }
> 
> let a = A()
> input(a)
> 
> 
> 
>> 下面是被转发的邮件:
>> 
>> 发件人: frogcjn at 163.com <mailto:frogcjn at 163.com>
>> 主题: 回复: [swift-evolution] Union instead of Optional
>> 日期: 2016年5月15日 GMT+8 18:00:55
>> 收件人: Austin Zheng <austinzheng at gmail.com <mailto:austinzheng at gmail.com>>
>> 
>> 
>> Enum and Union are two things.
>> 
>> If you use Enum to implement Union, you should announce it with case name.
>> 
>> Another issue using enum instead of union is that,  union can combine types as many as possible, you just write ( A | B | C ... | Z), but for enum, you should carefully announce it for each case. 
>> 
>> 在 2016年5月15日,15:22,Austin Zheng <austinzheng at gmail.com <mailto:austinzheng at gmail.com>> 写道:
>> 
>>> In addition, not everything in Swift can be modeled in terms of inheritance relationships.
>>> 
>>> I'm a little curious as to why union types keep on coming up, when enums can do everything they can and much more (methods, constraints on generic types, conformance to protocols).
>>> 
>>> Austin
>>>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>> 
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160515/5b8da41d/attachment.html>


More information about the swift-evolution mailing list