Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Julia multiple dispatch not matching subtypes

Tags:

julia

Can someone help me understand why this julia function definition isn't matched by my attempt to use it seen below?

My naive assumption is that the Array{ASCIIString,1} that is being passed into the function should match the function definition of Array{AbstractString,1}, and so on.

julia> function test(a::Array{AbstractString,1}, b::AbstractString, c::Any) end
test (generic function with 1 method)

julia> test([""],"","")
ERROR: MethodError: `test` has no method matching test(::Array{ASCIIString,1}, ::ASCIIString, ::ASCIIString)
Closest candidates are:
  test(::Array{AbstractString,1}, ::AbstractString, ::Any)

julia>
like image 206
David Parks Avatar asked Oct 24 '25 15:10

David Parks


1 Answers

I think it is worthwhile turning my two comments above into an answer.

As @DanGetz indicated, the important phrase here is invariant. In this particular case, this principle implies that ASCIIString <: AbstractString evaluates to true, but Array{ASCIIString, 1} <: Array{AbstractString, 1} evaluates to false. So for the function defined as in your question to work, you would need to pass in an array a with eltype(a) evaluating to AbstractString. Passing in a with eltype(a) evaluating to ASCIIString doesn't work, because this is not a subtype of Array{AbstractString, 1}.

To solve your problem, you need type parameters. If you want to only define the function for the case where the type of b matches eltype(a), then you would use:

function test{T<:AbstractString}(a::Array{T}, b::T, c::Any)

If you want to allow the type of b to differ from eltype(a), but enforce b to be a subtype of AbstractString, you would use:

function test{T<:AbstractString}(a::Array{T}, b::AbstractString, c::Any)
like image 62
Colin T Bowers Avatar answered Oct 27 '25 08:10

Colin T Bowers



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!