Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

f(x::Array{Real}) does not except f(x::Array{Float64}) in Julia

Tags:

julia

consider the following example in julia

function f(x::Array{Real,1}, y::Real)
    return [x..., y]
end

arr = [1,2,3]
f(arr, 4.0)

when I run this code, I get the following error

ERROR: LoadError: MethodError: no method matching f(::Array{Int64,1}, 
::Float64)
Closest candidates are:
f(::Array{Real,1}, ::Real) at ...

is there any way to fix this?

like image 409
Mohammed_Sabbah Avatar asked Sep 14 '18 10:09

Mohammed_Sabbah


1 Answers

You should write:

function f(x::Array{<:Real,1}, y::Real)
    return [x..., y]
end

This behavior is explained in this section https://docs.julialang.org/en/latest/manual/types/#Parametric-Types-1 of the Julia manual.

The problem is that Array{Float64,1} is not a subtype of Array{Real,1} but is a subtype of Array{<:Real,1}.

You can check it by running the following code:

julia> Array{Float64,1} <: Array{Real,1}
false

julia> Array{Float64,1} <: Array{<:Real,1}
true

Mentally you can to read Array{<:Real,1} as any vector whose element type specification is a subtype of Real, while Array{Real,1} means a vector whose element type specification is exactly Real. Note that you can construct the latter vector, and it is sometimes useful:

julia> Real[1, 1.0]
2-element Array{Real,1}:
 1
 1.0

(note that 1 and 1.0 were left as-is, i.e. as int and float), whereas:

julia> [1, 1.0]
2-element Array{Float64,1}:
 1.0
 1.0

did the conversion of both elements to float.

Additionally the reason why Julia treats Array{Real, 1} and Array{Float64, 1} as subtypes of each other is that both arrays have different storage format. Array{Float64, 1} simply stores floats (as Float64 is a concrete type) whereas Array{Real, 1} will store pointers to arbitrary reals.

like image 87
Bogumił Kamiński Avatar answered Nov 15 '22 09:11

Bogumił Kamiński