Julia struct error "no method matching iterate"

Viewed 213

While trying to understand parametric structs in Julia, I defined following struct as a subtype of AbstractSet

struct MySet{T} <: AbstractSet{T}
    st::Vector{T}
    MySet(x::Vector{T}) where {T} = new{T}(x)
end

However, I get following error when I try to create a new object of type MySet

julia> MySet([1,2])

       MethodError: no method matching iterate(::MySet{Int64})
       Closest candidates are:
       iterate(::Union{LinRange, StepRangeLen}) at ~/julia-1.7.1-linux-x86_64/julia- 
       1.7.1/share/julia/base/range.jl:826 
       iterate(::Union{LinRange, StepRangeLen}, ::Integer) at ~/julia-1.7.1-linux- 
       x86_64/julia-1.7.1/share/julia/base/range.jl:826
       iterate(::T) where T<:Union{Base.KeySet{<:Any, <:Dict}, 
       Base.ValueIterator{<:Dict}} at ~/julia-1.7.1-linux-x86_64/julia- 
       1.7.1/share/julia/base/dict.jl:695

Can someone help me understand why I am getting this error.

1 Answers

The MySet object gets created as you can see here:

julia> x = MySet([1,2]);

julia> x.st
2-element Vector{Int64}:
 1
 2

The problem is that it is not displayed correctly. The reason is that AbstractSet have a custom show method that gets called for them which assumes that your AbstractSet object is iterable.

What you can do to learn what minimal set of methods you should implement for AbstractSet until it gets documented is by writing:

julia> subtypes(AbstractSet)
5-element Vector{Any}:
 Base.IdSet
 Base.KeySet
 BitSet
 Set
 Test.GenericSet

julia> using Test

julia> methodswith(GenericSet)
[1] isempty(s::GenericSet) in Test
[2] iterate(s::GenericSet, state...) in Test
[3] length(s::GenericSet) in Test

The reason I pick GenericSet is that it is documented as:

help?> GenericSet
search: GenericSet GenericString GenericDict GenericOrder GenericArray

The GenericSet can be used to test generic set APIs that program to
the AbstractSet interface, in order to ensure that functions can work
with set types besides the standard Set and BitSet types.

so what GenericSet defines should be the minimum that AbstractSet interface requires.

(above I show you the full process you could use to discover what is needed, as guessing that GenericSet should be checked is non-obvious without the previous steps)

Related