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

Joe Groff jgroff at apple.com
Tue Oct 4 12:52:07 CDT 2016


> 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.

-Joe
> 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 <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/20161004/9940b317/attachment.html>


More information about the swift-evolution mailing list