Skip to content

Instantly share code, notes, and snippets.

@ollieatkinson
Last active February 20, 2024 13:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ollieatkinson/9fa246abf21a09a52d7c7c6e6149dc1e to your computer and use it in GitHub Desktop.
Save ollieatkinson/9fa246abf21a09a52d7c7c6e6149dc1e to your computer and use it in GitHub Desktop.
Equatable `Any` using existential
public func isEqual(_ x: Any, _ y: Any) -> Bool {
if let isEqual = (x as? any Equatable)?.isEqual(to: y) {
return isEqual
} else if let equatable = x as? AnyEquatable {
return equatable.isEqual(to: y)
} else {
return (x as? any OptionalProtocol).isNil && (y as? any OptionalProtocol).isNil
}
}
private func __isEqual(_ x: Any, _ y: Any) -> Bool {
isEqual(x, y)
}
extension Equatable {
fileprivate func isEqual(to other: Any) -> Bool {
self == other as? Self
}
}
protocol AnyEquatable {
func isEqual(to other: Any) -> Bool
}
extension Dictionary: AnyEquatable {
func isEqual(to other: Any) -> Bool {
guard let other = other as? [Key: Any] else { return false }
return allSatisfy { k, v in
other[k].map { __isEqual($0, v) } ?? false
}
}
}
extension Array: AnyEquatable {
func isEqual(to other: Any) -> Bool {
guard let other = other as? [Any] else { return false }
return Swift.zip(self, other).allSatisfy(__isEqual)
}
}
@ollieatkinson
Copy link
Author

Adaptation of https://gist.github.com/chriseidhof/e45f401cd1eb7bf2da949004cff618b4 with support for Dictionary and Array traversal

@ollieatkinson
Copy link
Author

ollieatkinson commented Feb 20, 2024

public protocol OptionalProtocol: ExpressibleByNilLiteral {
    associatedtype Wrapped

    var wrapped: Wrapped? { get }
    static var none: Self { get }

    static func some(_ newValue: Wrapped) -> Self
    func map<U>(_ f: (Wrapped) throws -> U) rethrows -> U?
    func flatMap<U>(_ f: (Wrapped) throws -> U?) rethrows -> U?
}

extension OptionalProtocol {
    public var isNil: Bool { wrapped == nil }
    public var isNotNil: Bool { wrapped != nil }
}

extension Optional: OptionalProtocol {
    @inlinable public var wrapped: Wrapped? { self }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment