# How to define \`:(==)\` on user-defined types for \`Set\` operations

**URL:** https://discourse.julialang.org/t/how-to-define-on-user-defined-types-for-set-operations/126391
**Category:** General Usage
**Tags:** sets
**Created:** [February 27, 2025, 4:27pm UTC](https://discourse.julialang.org/t/how-to-define-on-user-defined-types-for-set-operations/126391 "2025-02-27T16:27:08Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![drbergman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/drbergman/32/202226_2.png) [@drbergman](https://discourse.julialang.org/u/drbergman)
#### Post date: [February 27, 2025, 4:27pm UTC](https://discourse.julialang.org/t/how-to-define-on-user-defined-types-for-set-operations/126391/1 "2025-02-27T16:27:08Z")

</div>

I want to create a `Set{MyType}` object, but use a custom `Base.:(==)` to compare instances of `MyType`. It seems that the dispatch of `in` is not making use of `Base.:(==)` (or `Base.isequal` for that matter) _despite_ what the documentation says. Here is a MWE:

```julia
struct MyType
    a::Int
    b::Int
end

Base.:(==)(x::MyType, y::MyType) = x.a == y.a

x = MyType(1, 2)
y = MyType(1, 3)

@assert x == y

S = Set{MyType}()
push!(S, x)
@assert x in S
@assert y in collect(S)
@assert !(y in S) # this one is unexpected / I would want this to actually return true

push!(S, y)
@assert length(S) == 2 # a new element has been added
@assert y in S # y is now in S

```

I know there have been a couple threads on this before ([here](https://discourse.julialang.org/t/in-operator-for-set-of-sets/50474) and [here](https://discourse.julialang.org/t/create-a-user-type-set/75420)) but these seem to be centered around mutable elements in a `Set`.

My use-case is not so performance critical, so I’ll probably just use a `Vector{MyType}` and check if `y in S` before `push!`ing, but it would be helpful if the docs could be updated to reflect what seems (to the best of my testing/comprehension of the docs) unexpected behavior.

Finally, here’s a MWE also with overloading `Base.isequal`. The output makes it clear that only after collecting does `in` use `:(==)`.

```julia
struct MyType
    a::Int
    b::Int
end

function Base.:(==)(x::MyType, y::MyType)
    println("USING UPDATED :(==)")
    x.a == y.a
end

function Base.isequal(x::MyType, y::MyType)
    println("USING UPDATE isequal")
    x.a==y.a
end

x = MyType(1, 2)
y = MyType(1, 3)

@assert x == y

S = Set{MyType}()
push!(S, x)
@assert x in S
@assert y in collect(S)
@assert !(y in S) # this one is unexpected / I would want this to actually return true

push!(S, y)
@assert length(S) == 2 # a new element has been added
@assert y in S # y is now in S

```

#### `versioninfo()`

```julia-auto
Julia Version 1.11.3
Commit d63adeda50d (2025-01-21 19:42 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: macOS (arm64-apple-darwin24.0.0)
  CPU: 16 × Apple M4 Max
  WORD_SIZE: 64
  LLVM: libLLVM-16.0.6 (ORCJIT, apple-m1)
Threads: 1 default, 0 interactive, 1 GC (on 12 virtual cores)
Environment:
  JULIA_EDITOR = code
  JULIA_NUM_THREADS = 

```

---

<div class="post-metadata">

### Author: ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)
#### Post date: [February 27, 2025, 4:30pm UTC](https://discourse.julialang.org/t/how-to-define-on-user-defined-types-for-set-operations/126391/2 "2025-02-27T16:30:28Z")

</div>

That second topic — [Create a user-type set](https://discourse.julialang.org/t/create-a-user-type-set/75420) — is exactly your situation. The mutability is irrelevant here. When you re-define [`==`](https://docs.julialang.org/en/v1/base/math/#Base.:==), you must also symmetrically redefine [`hash`](https://docs.julialang.org/en/v1/base/base/#Base.hash).

---

<div class="post-metadata">

### Author: ![drbergman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/drbergman/32/202226_2.png) [@drbergman](https://discourse.julialang.org/u/drbergman)
#### Post date: [March 3, 2025, 3:51pm UTC](https://discourse.julialang.org/t/how-to-define-on-user-defined-types-for-set-operations/126391/3 "2025-03-03T15:51:34Z")

</div>

Thank you so much @mbauman! I guess what I really needed was confirmation that this was the right approach. Looking at that post again, I decided to use `AutoHashEquals.jl` and defined

```julia
using AutoHashEquals

@auto_hash_equals fields = (a,) struct MyType
    a::Int
    b::Int
end

```

And it’s working perfectly!
