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
