I'm sorry, but I don't understand the point you are trying to make.

If you pass in a value of type (A | B | C) to a function, what might you want 
to do with that value?

If you want to do one thing if the value is type A, something else if the value 
is type B, and something else if the value is type C, then you need to switch 
or otherwise type check the value at runtime. You can't get around this, no 
matter whether you use enums, protocols, generics, or union type.

If you want it to do something that A, B, and C all support, use a generic 
and/or a protocol. In this case limiting the inputs to only those three types 
is probably a design smell. The whole point of a shared interface is that it 
only matters that the interface is properly implemented by a type, not what 
that type is.

If you don't care about doing anything with the value, just make your function 
generic: func<T>(input: T).

Austin


> On May 16, 2016, at 3:29 AM, Cao Jiannan <[email protected]> wrote:
> 
> 
> 
> Consider this case:
> 
> class A {
>     var someCommonProperty: Int = 0
> }
> class B {
>     var someCommonProperty: Int = 0
> }
> class C {
>     var someCommonProperty: Int = 0
> }
> 
> protocol UnionABC {
>     var someCommonProperty: Int
> }
> 
> extension A: UnionABC {}
> extension B: UnionABC {}
> extension C: UnionABC {}
> 
> 
> ===================== If we using protocol
> 
> 
> func input(value: UnionABC) {
>     print(value.someCommonProperty) // Compiler will know their common 
> properties automatically.
>     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)
> 
> ===================== If we using union
> 
> func input(value: (A | B | C)) {
>     print(value.someCommonProperty) // Compiler will know their common 
> properties automatically.
> 
>     if value is A {
>         
>     } else if value is B {
>         
>     } else if value is C {
>         
>     } else {
>         // There no other cases, so the compiler trigger a warning.
>     }
> }
> 
> let a = A()
> input(a)
> 
> 
> =====================
> 
> If using generic enum,
> the compiler doesn’t know the type relation between generic union with 
> original type.
> class A and UnionOf3<A,B,C> are totally two different types, has no 
> relationship.
> But class A and (A | B | C) keeps a relationship.
> 
> If using union, these two cases will be allowed:
> 
> let a = A()
> let union: (A|B|C) = a // Automatically wrap.
> 
> a == union // Can be compared, Yes
> 
> sub-typing: 
> 
> var fn0: A->Void = {print(v0)}
> var fn1: (A|B)->Void = {print(v0)}
> 
> fn0 = fn1 // Original Type and Union Type has a sub-typing relationship, OK
> 
> var fn2: (A|B|C)->Void = {print($0)}
> 
> fn0 = fn2 // OK
> fn1 = fn2 // OK
> 
> 
>> 在 2016年5月16日,18:17,Austin Zheng <[email protected] 
>> <mailto:[email protected]>> 写道:
>> 
>> This doesn't explain how I can use 'value' once an A() is passed into the 
>> function:
>> 
>> func input(value: (A | B | C)) {
>>     
>> }
>> 
>> If A, B, and C are not related via protocol or class inheritance, then there 
>> is almost nothing you can do with value. Otherwise you still need to test 
>> against the concrete type using a case statement or a if-else ladder.
>> 
>> The other 'gain' is being able to call 'input(A())', rather than 
>> 'input(.caseA(A()))'. I agree that the first form is prettier than the 
>> second one. I also think you could make the language pervasively prettier 
>> and more expressive by allowing for all sorts of implicit conversions. At 
>> some point clarity at the point of use beats conciseness, especially when 
>> code within a complex codebase needs to be maintained.
>> 
>> I understand that this is largely a matter of style - different people value 
>> different things, and that's wonderful. I welcome a formal proposal 
>> submitted to the swift-evolution process, and if one appears I'm happy to 
>> consider it in more detail and argue for or against it based on that.
>> 
>> Austin
>> 
>> 
>> 
>> On Sun, May 15, 2016 at 3:34 AM, Cao Jiannan <[email protected] 
>> <mailto:[email protected]>> wrote:
>> 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)
>> 
>> 
>> 
>>> 下面是被转发的邮件:
>>> 
>>> 发件人: [email protected] <mailto:[email protected]>
>>> 主题: 回复: [swift-evolution] Union instead of Optional
>>> 日期: 2016年5月15日 GMT+8 18:00:55
>>> 收件人: Austin Zheng <[email protected] <mailto:[email protected]>>
>>> 
>>> 
>>> 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 <[email protected] 
>>> <mailto:[email protected]>> 写道:
>>> 
>>>> 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
>>>>>> [email protected] <mailto:[email protected]>
>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>> 
>>>>> _______________________________________________
>>>>> swift-evolution mailing list
>>>>> [email protected] <mailto:[email protected]>
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 
>> 
> 

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to