universal_amateur
universal_amateur

Reputation: 149

Julia: Function Arguments – Type Specification of Arrays

It seems like i missed something about multiple dispatch + parametric types:

Integer is an abstract supertype of all integer types, so the method f(arg::Integer) works as expected:

f(arg::Integer) = println("an integer")
# f(42) prints "an integer"
# f(UInt8(42)) prints "an integer"

But if i you try the same with an one-dimensional Array of Integers as an argument type, julia answers with an error message:

f(arg::Array{Integer, 1}) = println("an array with integers")
f(arg::Array{Signed, 1}) = println("an array with signed integers")
# f([1,2,3]) gives "no method matching f(::Array{Int64,1})..."

Any idea what is wrong here? – Thanks in advance!

Upvotes: 2

Views: 418

Answers (1)

Nils Gudat
Nils Gudat

Reputation: 13800

You're running into parametric type invariance, that is the nice orange warning box in the manual here.

Citing the relevant part:

Concrete Point types with different values of T are never subtypes of each other:

julia> Point{Float64} <: Point{Int64}
false

julia> Point{Float64} <: Point{Real}
false

Warning

This last point is very important: even though Float64 <: Real we DO NOT have Point{Float64} <: Point{Real}.

For your example, you would need:

f(arg::Array{<:Integer, 1}) = println("an array with integers")
# Alternatively f(arg::Array{T, 1}) where T <: Integer = println("an array with integers")
f(arg::Array{Signed, 1}) = println("an array with signed integers")

The first method is then a fall-back for general integer Arrays, and the second can be called with the specific type Array{Signed, 1}:

julia> f([1,2,3])
an array with integers

julia> f(Array{UInt8, 1}([1,2,3]))
an array with integers

julia> f(Array{Signed, 1}([1,2,3]))
an array with signed integers

Upvotes: 5

Related Questions