# How to compare two vectors whose elements are equal but their types are not the same?

Suppose we have two types, `A` and `B`, which are just two wrapper types of `Vector`s:

``````struct A{T} <: AbstractVector{T}
data::Vector{T}
end
struct B{T} <: AbstractVector{T}
data::Vector{T}
end

Base.size(x::Union{A,B}) = (6,)

Base.getindex(x::Union{A,B}, i) = getindex(x.data, i)
``````

And comparing two instances of them:

``````julia> x = collect(1:6);

julia> a = A(x)
6-element A{Int64}:
1
2
3
4
5
6

julia> b = B(x)
6-element B{Int64}:
1
2
3
4
5
6

julia> a == b
true

julia> a === b
false
``````

But what I actually is that `a == b` is `false` since `A` and `B` are of different types. What should I do?

I’m not sure you should make them subtypes of `AbstractVector`. The equality behavior is inherited from it, and in many places we assume that `AbstractVector` is what it says it is: a vector object whose specific type rarely matters.

You could instead define `abstract type PickyVector{T} end` and make them subtypes of `PickyVector`, and then define generic operations on `PickyVector`.

3 Likes

Thank you for your answer. But I am defining them as vectors because I want to take advantage of the existing array interfaces and various methods. If I do not subtype them from `AbstractVector`s, I will have to write a lot of code by myself.

Can I just redefine `==` for `A` and `B`?

``````for op in (:(==), :isequal, :isapprox)
@eval begin
Base.\$op(a::A, b::B) = false
Base.\$op(b::B, a::A) = false
end
end
``````

This obviously works to solve your short term problem. However, this will create an inconsistency with how we expect `AbstractArray`s to work, which can be detrimental to the overall user experience.

However, a) if these types are not exposed for anybody else to use, or b) if it’s clearly communicated that these are *not* fully-featured arrays, and proper expectations of their limitations and differences are set (and if those limitations are intuitive to users), then you should be ok.

I think a good example of this is `setindex!` for `SArray`s from StaticArrays.jl. Even though `SArray` subtypes `AbstractArray`, and `setindex!` is required to be implemented for all `AbstractArray`s, the purpose of `SArray`s makes it fairly obvious that it shouldn’t have this method.

Thank you. If I do not subtype from `AbstractArray`s, what specific interface can I implement? Is ArrayInterface.jl usable?

Augmenting `Base` functions with methods implementing different semantics is often a risky proposition. What you’re asking for is not how `==` is designed to be used. Many functions across `Base` and the larger package ecosystem depend on the existing semantics for correct operation.

Instead, I’ll suggest you consider implementing a new function for your purpose. Your objects can continue to behave across the ecosystem in all the ways you would expect, using the default `==`. For example, this new function appears to implement what you’d like:

``````sametypeequal(x::T, y::T) where T = x == y
sametypeequal(x, y) = false
``````

You can continue to use the array interface (with the default `==`) and just call this function where you need these different semantics. If this is insufficient for your purposes (e.g., your objects don’t behave how you want with some other function that depends on `==`), perhaps you can point out where those issues are and people can try to help.

2 Likes