Let struct instance equal each other just depending on their struct name

I have a abstract ttt, which owe two subtypes Tec1,Tec2 :

abstract type ttt end
struct Tec1{T} <: ttt
    n::T
end
struct Tec2{T} <: ttt
    n::T
end

I make the instances genrerated from the two struct equal each other just depending on their struct name:

Base.hash(x::T,h::UInt) where {T <: ttt}=hash(T.name,hash(0x7d6979235cb005d0, h))
Base.:(==)(x::T,y::N) where {T <: ttt, N <: ttt}=T.name == N.name

So:

Tec1(10) == Tec1(100)
true

Tec1(10) == Tec2(100)
false

haskey(
    Dict(
        Tec1(10) => 100
        ),
    Tec1(100)
    )
true

But, when I make another struct wrapping the two struct

struct Tel{T}
    n::T
end

There happend:

Tel(Tec1(10)) == Tel(Tec1(100))

false

In my view, Tuple isa just a unmutable struct, and (1,Tec1(10)) == (1,Tec(100)) is true, the why Tel(Tec1(10)) == Tel(Tec1(100)) is false?

So, what should I do to make this happen:

Tel(Tec1(10)) == Tel(Tec1(100))
true

You haven’t defined an equality method for Tel, so afaik, it falls back to ===.
BTW it isn’t necessary to access the name of the struct Tec1. Just use dispatch:

Base.:(==)(::T, ::T) where {T<:ttt} = true

Also, struct names should be capitalized: Ttt, not ttt.

2 Likes

Where does the field name come from? It doesn’t appear to be defined:

The field name dosen’t come from the instance of Tec1, it comes from typeof(tec1) or T
It can be accessed in this way :

test1(x::T) where T=begin
    println(T.name)
end

-> test1(10)
typename(Int64)

Thanks, this style is much more cleaner than the original one.

Tel(Tec1(10)) == Tel(Tec1(100))

This falls back to === : Tel(Tec1(10)) === Tel(Tec1(100)), then this will check Tel(Tec1(10)).n === Tel(Tec1(100)).n, while Tec1(10) === Tec1(100) isa false.
Is there a way I can compel that :

Tec1(10) === Tec2(100)
true

No, I don’t think so. And you definitely shouldn’t. x === y means that there is no way to distinguish between x and y. But in your case there clearly is, since x.n and y.n are different.

2 Likes