alskipp/Swift-Adventures-In-Monad-Land

enum is Equatable

Closed this issue · 3 comments

Following code is not needed here

func ==(lhs:ThreatLevel, rhs:ThreatLevel) -> Bool {
    return lhs.rawValue == rhs.rawValue
}

Because enum is already Equatable as following:

func test<T: Equatable>(p1: T, p2: T) -> Bool {
    return p1 == p2
}

enum E {
    case e, f
}
test(E.e, E.e) // true
test(E.e, E.f) // false

enum RawE: String {
    case e = "e", f = "f"
}
test(RawE.e, RawE.e) // true
test(RawE.e, RawE.f) // false

Now, Thank you for awesome playgrounds. I love it

Hi @norio-nomura,
Thanks for pointing this out (I was unaware that enums are Equatable by default). I did some searching and found this from Apple:

“Enumeration member values without associated values are also hashable by default.”

Hashable obviously implies Equatable, but Apple don't seem to mention that enums are Equatable by default in the Swift book (unless I've missed something?).

Interestingly, using your example, the hash value of the enum without a raw value is nicely ordered:

E.e.hashValue // 0
E.f.hashValue // 1

But it's probably very bad form to rely on hash values to implement Comparable instead of using a raw value of Int.

It would be great if Swift had derivable Protocol conformance (like Haskell) as Printable is a bit laborious to implement for enums. Perhaps like:

enum ThreatLevel deriving : Comparable, Printable {
    case Low, Guarded, Elevated, High, Severe
} // compiler creates default implementations of Comparable and Printable - yay!

Maybe in the next major release of Swift something like this will be possible?


Anyway, I'll update the code based on this information - thanks again for raising the issue.

All the best,
Al

Just pushed an update that removes the Equatable code and adds a bit of explanation.

Cheers!