Have a function accept an argument of type `Array{Real}`

I have a function

function square(a::Real)
    return a[1]^2
end

this works with both Int64 and Float64. But if I make it accept an array of Reals I get this

julia> function square(a::Array{Real})
           return a[1]^2
       end
square (generic function with 1 method)

julia> square([Float64(2)])
ERROR: MethodError: no method matching square(::Vector{Float64})
Closest candidates are:
  square(::Array{Real}) at REPL[1]:1
Stacktrace:
 [1] top-level scope
   @ REPL[2]:1

julia> square([Int64(2)])
ERROR: MethodError: no method matching square(::Vector{Int64})
Closest candidates are:
  square(::Array{Real}) at REPL[1]:1
Stacktrace:
 [1] top-level scope
   @ REPL[3]:1

How can I correctly type a function that can accept an array of Real numbers?

Julia type parameters are invariant, i.e. Array{Subtype} is not a subtype of Array{BaseType}.
For a function to accept arrays of any subtype of real numbers, you have to explicitly express that:

function square(a::Array{T} where T<:Real)
1 Like

A shorter syntax would be a::Array{<:Real} but then you have no handle on the type, so it depends what you need

1 Like

This is in the Julia FAQ:

You can solve this problem with something like foo(bar::Vector{T}) where {T<:Real} (or the short form foo(bar::Vector{<:Real}) if the static parameter T is not needed in the body of the function).

See the FAQ and the linked sections of the manual for more explanation.

2 Likes