Can't get isequal to compare custom struct with Int

I am having trouble getting isequal to work for a user created struct. Below is an example that shows what I’m doing. I don’t understand what I’m doing wrong.

struct MyStruct
    value::Int
end

import Base.+
(+)(x::MyStruct,y::Int) = MyStruct(x.value + y)
import Base.isless
import Base.<
isless(x::MyStruct,y::Int) = (x.value < y)::Bool
import Base.isequal
import Base.==
isequal(x::MyStruct,y::Int) = (x.value == y)::Bool
isequal(x::MyStruct,y::MyStruct) = (x.value == y.value)::Bool

using Test
ms1 = MyStruct(5)
ms2 = MyStruct(5)
@test(ms1 == ms2)
@test(ms1 + 1 == MyStruct(6))
@test(ms1 < 6)
@test_broken(ms1 == 5)  # Doesn't work ???

The following works for me:

struct MyStruct
    value::Int
end

import Base.+
(+)(x::MyStruct,y::Int) = MyStruct(x.value + y)
import Base.isless
import Base.<
isless(x::MyStruct,y::Int) = (x.value < y)::Bool
import Base.isequal
import Base.==
(==)(x::MyStruct,y::Int) = (x.value == y)::Bool
(==)(x::MyStruct,y::MyStruct) = (x.value == y.value)::Bool

using Test
ms1 = MyStruct(5)
ms2 = MyStruct(5)
@test(ms1 == ms2)
@test(ms1 + 1 == MyStruct(6))
@test(ms1 < 6)
@test(ms1 == 5)

isequal and == are different.

1 Like

Thanks. (duh)

But now I’m confused, why does < resolve to isless(), but == does not resolve to isequal?

I don’t know about the rationales, but the documentation states, that isequal contains special handling for floating points (NaN for example) and isless seems to be meant mainly for implementing total orders on non numeric types.

Generic == resolves to ===:

# core numeric operations & types
==(x, y) = x === y

at share/julia/base/Base.jl

and

isequal(x, y) = x == y

< on the other side falls back to isless:

<(x, y) = isless(x, y)

while there is no generic isless.

I don’t know if the fallback ==(x,y) = x === y could be made type-specific to and make == fallback to isequal by default. Maybe? (that would be breaking, though). But there might be a deeper reason for that difference.

See GitHub - andrewcooke/AutoHashEquals.jl: A Julia macro to add == and hash() to composite types. to automate these method definitions.

1 Like