Function methods based solely on element type of array of arbitrary dimension

I’m new to Julia, so my question may be naive or obvious. I’ve searched the documentation and elsewhere but can’t find an answer. Is it possible to define a function in Julia that takes as an argument an array of arbitrary dimension and have different methods that are based only on the type of the elements in the array (and not the dimensions of the array)?

Probably not. Even if you could, you probably wouldn’t want to though. It’s hard to imagine anything you could do with an array that would be efficient if you didn’t know the dimension. (Note in case this is the confusion: dimension isn’t size. Dimension is Vector vs Matrix vs higher order). What’s your usecase for wanting this?

Can you be more specific about the kinds of input and output you want?

1 Like

Something like?

f(::Array{Float64}) = 1
f(::Array{Int}) = 2
3 Likes

Thanks for your responses. I’m not so much interested in this for efficiency as asserting that the arguments passed to the function make sense. For my use case, I have a function that takes an array as one argument and a 1D array of arrays as the other. I’d like to check that the array is in the array of arrays.

function contains(array::AbstractArray,arrays::AbstractArray)::Bool
    any([isapprox(array,arrays[i]) for i=1:length(arrays)])
end

The array can be scalars, vectors, matrices, …, and the elements of each should be real numbers.

1 Like

You can do this fairly easily with a two-phase dispatch. All you need to do is have the “primary” method of this function call the function again with an extra parameter that it can then dispatch on, using the standard eltype function to compute it:

myfunc(arr::AbstractArray, other_params) = myfunc(arr, other_params, eltype(arr))

myfunc(arr::AbstractArray, other_params, elty::Type) = …general case code…

myfunc(arr::AbstractArray, other_params, elty::Type{<: Real}) = …code for when the elements are reals…

myfunc(arr::AbstractArray, other_params, elty::Type{<: Int}) = …code for when the elements are ints…

2 Likes

That is expressed as

function contains(base::AbstractArray, arrays::AbstractVector{<:AbstractArray{<:Real}})
    any(isapprox(base, a) for a in arrays)
end

or, more verbosely

function contains(base::AbstractArray, arrays::AbstractVector{A}) where {A<:AbstractArray{T} where T<:Real}
    any(isapprox(base, a) for a in arrays)
end

Note that materializing the generator in a vector is not necessary. Generators are iterable, so functions like any, all, sum etc. may work on them directly.

Enforcing very strict input type constraints is not very Julian, though. A style more likely to find is

contains(item, itr; eq = isequal) = any(x -> eq(item, x), itr)

Then, you can use it as contains(array, arrays, eq = isapprox). As Julia is not statically compiled, neither type-constrained nor duck-typed function are going to produce compile-time errors anyway.

5 Likes