I'm trying to maintain code reusability whilst using the Array
type, but am unsure of how to proceed without allowing "illegal" types through. Example functionality:
foo = function(x::Array{Number,2})
print(x)
end
foo([1 2 3; 4 5 6; 7 8 9])
# 15
foo([1 2 3])
# MethodError: no method matching (::Array{Int64,1})
# Closest candidate is (::Array{Number,2})
foo(["alpha" "beta"; "pi" "rho"])
# MethodError: no method matching (::Array{String,2})
# Closest candidate is (::Array{Number,2})
However, the first example, foo([1 2 3; 4 5 6; 7 8 9])
comes back with MethodError: no method matching (::Array{Int64,2})
despite (::Array{Number,2})
theoretically being a valid promotion. I don't want to have to manually convert for every function call; nor do I want to have to declare all arrays to be of the Array{Number,2}
type. I know that I could instead replace the function call with:
foo = function(x::Array)
print(x)
end
However, this allows arrays of any dimensionality and type into the function. The only other alternative I can think of is to add boilerplate code where I initially allow any and all arrays in, check their typing and size manually, and go from there, but this feels inelegant.
Any suggestions? Thanks in advance. (Note: I am using Julia 0.6.3)
Use Matrix{<:Number}
instead of Array{Number, 2}
as type restriction and all will work (also Array{<:Number, 2}
would work).
In short Matrix{Int64}
is not subtype of Matrix{Number}
, but is a subtype of Matrix{T} where {T<:Number}
which can be expressed as Matrix{<:Number}
if you do not use T
in the body of the function.
The Julia manual here https://docs.julialang.org/en/v0.6.4/manual/types/#Parametric-Abstract-Types-1 and here https://docs.julialang.org/en/v0.6.4/manual/methods/#Parametric-Methods-1 describes in detail how subtyping in parametric types works in Julia 0.6. Then I think that you can check out this recent SO question Julia: creating a method for Any vector with missing values to understand how more complex cases of subtyping can be handled.