Multiple dispatch of `in`

I’d like to customise how in works for a struct I’ve created as only some fields matter. I’d like it to work like this where here I just want to check the dogs breeds:

struct Dog
    breed
    name
end

a = Dog("husky", "a")
b = Dog("husky", "b")
c = Dog("labrador", "c")

dogs = [b]
a in dogs # true
c in dogs # false

I think in uses Base.:== but I’m not sure how to extend this? Extending Base.isequal doesn’t have the correct affect.

How can I do this?

N.B. in the Python world this would the implementation of __eq__

Base.:(==)(a::Dog, b::Dog) = a.breed == b.breed
Base.hash(a::Dog, h::UInt) = hash(a.breed, h)

where if you change the definition of equality you also need to change Base.hash so that hash tables (e.g. Set data structures) work. (By default, isequal calls ==.)

Alternatively, you define your own in-like function (e.g. the ∈ᵇ operator) to be whatever you want, while leaving equality as-is.

2 Likes

Thank you I was missing the parentheses around ==. I’ve chosen to extend == as this means I get the in functionality for free. Maybe I’ll come to regret this, but such is learning!