[swift-evolution] [Pitch] Hashable types on RawRepresentable enums or a protocol for custom enum-like types

Adrian Zubarev adrian.zubarev at devandartist.com
Tue Oct 4 13:07:21 CDT 2016

Doesn’t this imply more performance cost? Don’t get me wrong but the value here is not fixed and computed all over again which might waste resources if the calculation is complicated. Sure we could build some workarounds here and there, but the codebase won’t get any prettier after that.

Another though is that enums just need stored properties to solve the main problem here nicely. I don’t remember what the outcome of that talk was back then. I’ll search for that conversation soon.

Anyways, thank you Joe for showing us the possible workaround.

Adrian Zubarev
Sent with Airmail

Am 4. Oktober 2016 um 19:52:11, Joe Groff (jgroff at apple.com) schrieb:

On Oct 3, 2016, at 12:50 PM, Adrian Zubarev via swift-evolution <swift-evolution at swift.org> wrote:

Hi there,

I’m interested if this idea has some potential future in Swift or not.

Currently RawRepresentable enums accept only a subset of literal types like String, Character and the Integer family (enum Name : String { … }).

Sometimes this is not enough for my use-case and I wish I could feed my enums with other Hashable types!

As a workaround I can create a custom struct or even a class and conform it to RawRepresentable and fake an enum with some static variables (similar to what is done with OptionSet types).

The literal type constraint only affects the sugar syntax using the ': String' and 'case X = 1' syntax. If you write an enum's conformance explicitly, you can use any raw type you like:

enum Test: RawRepresentable {
  case something, nothing

  init?(rawValue: A) {
    switch rawValue.value {
    case "something": self = .something
    case "nothing": self = .nothing
    default: return nil

  var rawValue: A {
    switch self {
    case .something: return A(value: "something")
    case .nothing: return A(value: "nothing")

though it's up to you at this point to guarantee the 1:1 correspondence between raw values and enum values that RawRepresentable assumes.

The problem there is that I cannot use the same switch pattern matching like with enums. I’d wish either enums could accept Hashable types (maybe with some restriction) or the existence on a protocol to build custom enum-like types with strucs/classes and use the same switch pattern matching.

struct A : Hashable { /* implement everything */ }

// Variant 1:
enum Test : A {
    case something = A(rawValue: A(value: "something"))
    case nothing = A(rawValue: A(value: "nothing"))   

// Variant 2:

protocol SomeFancyName : RawRepresentable { … }

struct Test : SomeFancyName {
    let rawValue: A
    init?(rawValue: A) {
            // Implement + reject unwanted `A`s   
    static let something = A(rawValue: A(value: "something"))
    static let nothing = A(rawValue: A(value: "nothing"))

let value = Test.something

switch value {
case .something:
    // handle
case .nothing:
    // handle
// Because of `SomeFancyName` the switch can use enum-like pattern matching + does not need the `default` case when all cases are present

Adrian Zubarev
Sent with Airmail

swift-evolution mailing list
swift-evolution at swift.org

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20161004/d1323003/attachment.html>

More information about the swift-evolution mailing list