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?
Something like?
f(::Array{Float64}) = 1
f(::Array{Int}) = 2
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.
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…
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.