Enum's all implement protocol Foo: best way to get allCases as [Foo] If Foo is Hashable?

I’m referring to your original statement:

I need Foo to be either Hashable or Identifiable

This is not possible without writing your own code.

That snippet was just a suggestion to the original poster what he can do to achieve the wanted result via slightly different means.

Here's yet another option, perhaps what the original poster refers to as type erasure (methinks)
protocol ColorCase {
    var name: String { get }
    var color: Color { get }
}

enum A: String, ColorCase, CaseIterable {
    case a, b, c
    var name: String { rawValue }
    var color: Color { .red }
}

enum B: String, ColorCase, CaseIterable {
    case one, two, three
    var name: String { rawValue }
    var color: Color { .green }
}

struct ContentView: View {
    var body: some View {
        let a: [AnyHashable] = A.allCases
        let b: [AnyHashable] = B.allCases
        let cases = a + b
        
        List {
            ForEach(cases, id: \.self) {
                let v = $0 as! ColorCase
                Text(v.name)
                    .foregroundColor(v.color)
            }
        }
    }
}
1 Like

Even with "generalized existential", we'll still have to hand code type erase? I thought the compiler will be able to do it for us.

The compiler cannot do it for you; it is impossible for an existential to conform to itself automatically when there are certain Self or associated type requirements.

1 Like

It looks Swift wants you to gear away from doing, say:

var items: [Equatable] = [Apple(), Orange()] // not current swift

because then you may want to write:

items[0] == items[1]

which is comparing apples to oranges, and while some other languages are fine with this concept ("if types don't match the two things are obviously not equal, if types do match - let's have a closer look") Swift wants to prohibit comparing apples to oranges at compile time. That's my current understanding of the "Protocol can't conform to the protocol itself" and related existential gotchas.

Protocols with self or associated type requirements and Protocols without those requirements are two different kingdoms with very different law systems.

The remaining missing feature is to allow an any Equatable: Equatable extension that specifies the heterogeneous conformance.

What is he talking about? Does he mean the any MyProtocolWithSelfOrAssociatedType: MyProtocolWithSelfOrAssociatedType? Is this "automatic type erasure"?

https://twitter.com/jckarter/status/1531686627013033985

I think any FooProtocol is a distinct type from FooProtocol and therefore can be made to conform by adding a custom conformance.

It's not really "self-conformance".

1 Like