I can solve the last one!  You often want phantom types in Swift, and they can 
be had albeit a bit unsafely with a "sealed conformance" to a common protocol 
and a set of no-case (for phantom types) or single-case (for singleton types) 
enums.  This this you can do terrible things like create type-level Nats 
https://gist.github.com/CodaFi/7bb3bd00f04a9b26fd71 and things indexed by them 
like Fin or even recover light dependent pattern matching with type(of:).

~Robert Widmann

2016/09/27 18:59、Karl via swift-evolution <[email protected]> のメッセージ:

> 
>> On 27 Sep 2016, at 18:55, Joe Groff via swift-evolution 
>> <[email protected]> wrote:
>> 
>> 
>>> On Sep 26, 2016, at 8:51 AM, Jérôme Duquennoy via swift-evolution 
>>> <[email protected]> wrote:
>>> 
>>> Summary
>>> The aim of this proposal is to offer a new syntax to ease some uses of 
>>> enums with payload.
>>> 
>>> Situation to improve:
>>> Enums makes it possible to have explicate typing where it was not possible 
>>> before. A classic example of that is filling a dictionary with data coming 
>>> from a file or a stream (json, plist, …) : the types of possible values is 
>>> finite : arrays, dicts, int, double, bool or string for json for exemple.
>>> An enum can represent this finite range of possible types, its make the 
>>> code and the API more self-documented.
>>> Then, you have two possibilities to deal with this enum:
>>> - using switch statements
>>> - using the if case syntax introduced by swift 2
>>> 
>>> The drawback is that those two solutions can lead to writing code with high 
>>> visual complexity, even though the logic behind is pretty simple.
>>> 
>>> Consider this example of a data dictionary, that a web service could have 
>>> returned:
>>> - book
>>> - title: 
>>> - author:
>>>   - name: Apple
>>>   - age: 40
>>> 
>>> We can decode this in a variable of type [String:Value], where Value is:
>>> 
>>> enum Value {
>>> case integer(value: Int)
>>> case string(value: String)
>>> case dict(value: [String:Value])
>>> case null
>>> }
>>> 
>>> Here is a snippet of code to access the age of the author:
>>> 
>>> if case .dict(let book) = data {
>>> if case .dict(let author) = book["author"] ?? .null {
>>>   if case .integer(let age) = author["age"] ?? .null {
>>>     // now we have the age
>>>   }
>>> }
>>> }
>>> 
>>> The multiple indentation levels can rapidly make this code unattractive to 
>>> read, and we need to add a null case to the enum to deal with optional 
>>> values.
>>> 
>>> Proposed solution:
>>> I suggest to add a new syntax, using the case keyword to ease access to the 
>>> payload of such enums :
>>> 
>>> let payloadContent = case? .enumCase(variable)
>>> 
>>> The payloadContent variable will be an optional, that can be either nil, or 
>>> contain the payload of enumCase.
>>> If the payload contains multiple variables, payloadContent will be a tupple.
>>> This syntax can accommodate an optional variable as an input. If the value 
>>> of variable is nil, then payloadContent will be nil.
>>> Only enum cases with a payload can be used with this syntax (it would make 
>>> no sens for cases without a payload).
>>> 
>>> With that syntax, the null case of the enum can be removed, and the code to 
>>> access the age becomes:
>>> 
>>> let book = case? .dict(inputData)
>>> let author = case? .dict(book?["author"])
>>> let age = case? .integer(author?["age"])
>>> 
>>> Advantages:
>>> - It leverages the well established notion of optional, and similar logic 
>>> already exists in the language (for the as? operator notably).
>>> - It does not add a new keyword
>>> - It promotes the use of enum to enforce explicit typing, which leads to 
>>> more self-documenting code
>>> - It reduces the complexity of the code in situations such as the one of 
>>> the exemple
>>> 
>>> Drawbacks:
>>> - It adds a third use of the case keyword. 
>>> - In the proposed syntax, the variable between parenthesis is not the 
>>> payload, but the variable to decode. This might be disturbing, as it 
>>> differs from the other syntax of enum values.
>>> - If the payload is an optional, it is not possible to differentiate a 
>>> non-matching case and a matching case a nil payload.
>>> 
>>> Alternatives:
>>> - Another syntax without parenthesis could be used to avoid the second 
>>> drawback:
>>> let payload = case? .enumCase variable
>>> 
>>> Impact on existing code:
>>> None, this is adding a new syntax
>>> 
>>> 
>>> This proposal would have no impact on the ABI, so it probably does not fit 
>>> the stage 1 of swift 4’s roadmap. But I would be glad to have your 
>>> feedback, so that I can have a proposal ready once we enter stage 2.
>>> So what your thoughts on that proposal ?
>> 
>> I think it's reasonable to want an expression for extracting the payload of 
>> a enum case as an Optional. Instead of introducing a new operator, though, 
>> we could say that the cases themselves behave as Optional properties of an 
>> enum, which would allow you to say:
>> 
>> if let book = inputData.dict,
>>  let author = book["author"].dict,
>>  let age = author["age"].integer { ... }
>> 
>> -Joe
>> _______________________________________________
>> swift-evolution mailing list
>> [email protected]
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> I was thinking the same thing. I’m finding myself writing a lot of 
> convenience accessors of the type:
> 
> enum MyEnum<T> {
>    case stateOne
>    case stateTwo(Array<T>)
>    case stateThree(T)
>    case stateFour(Error, T)
> 
>    var error : (Error, T)? {
>        if case .error(let r) = self { return r }
>        return .none
>    }
> }
> 
> It would be nice if the compiler could generate these style of accessors, 
> with the payload available as an optional tuple. Perhaps it would be called 
> `var stateFourData : (Error, T)?` or something predictable.
> 
> While I’m on the subject, sometimes I want every case of an enum to be its 
> own type, which is a subtype of the enum’s type - e.g. 
> MyEnum<Int>.stateThree.self. That would allow you to keep a collection of 
> MyEnum values which are guaranteed to all be the same case.
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> 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