Is there a Collection supertype between Set and Array? If not, how can a function be polymorphic over both Sets and Arrays (for iteration)?

Viewed 139

Is there in Julia a Collection type from which both Set and Array derive ?

I have both:

julia> supertype(Array)
DenseArray{T,N} where N where T

julia> supertype(DenseArray)
AbstractArray{T,N} where N where T

julia> supertype(AbstractArray)
Any

And:

julia> supertype(Set)
AbstractSet{T} where T

julia> supertype(AbstractSet)
Any

What I try to achieve is to write function that can take both Array or Set as argument, because the type of collection doesn't matter as long as I can iterate over it.

function(Collection{SomeOtherType} myCollection)
    for elem in myCollection
        doSomeStuff(elem)
    end
end
2 Answers

No, there is no Collection type, nor is there an Iterable one.

In theory, what you ask can be accomplished through traits, which you can read about elsewhere. However, I would argue that you should not use traits here, and instead simply refrain from restricting the type of your argument to the function. That is, instead of doing

foo(x::Container) = bar(x)

, do

foo(x) = bar(x)

There will be no performance difference.

If you want to restrict your argument types you could create a type union:

julia> ty = Union{AbstractArray,AbstractSet}
Union{AbstractSet, AbstractArray}

julia> f(aarg :: ty) = 5
f (generic function with 1 method)

This will work on both sets and arrays

julia> f(1:10)
5
julia> f(rand(10))
5
julia> f(Set([1,2,5]))
5

But not on numbers, for example

julia> f(5)
ERROR: MethodError: no method matching f(::Int64)
Closest candidates are:
  f(::Union{AbstractSet, AbstractArray}) at REPL[2]:1
Related