# Implement a function for Vectors of all subtypes

I have a problem i can’t find a solution for.
Lets say I have a abstract supertype

``````abstract A
``````

and a subtype

``````type B <: A
value::Vector
end
``````

(others might want to have `value` e.g. to be a matrix or something)

And I implemented a few functions for each subtype, maybe `f1(p::B)::Float64` (and for other subtypes, too…) and now I’d like to implement a function such as

``````function myVFun(p::Vector{A},lambda::Integer)
sum( [ f1(v) for v in p] )
# but really this is of course more complicated involving 2-3 functions all available for each subtype of A
return ...
end
``````

Somehow the method dispatch does not call this function if I now have a `Vector{B}` (because this is not a subtype of `Vector{A}`?). But however I qould like to be able to implement (and call) such a function using vectors of subtypes. Because all functions I apply to the elements of `p::Vector{A}` are available for `B <: A`

How can I do that?

Vector{B} is not a sub-type of vector{A}

from the docs:

Even though Float64 <: Real we DO NOT have Point{Float64} <: Point{Real}.
In other words, in the parlance of type theory, Julia’s type parameters are invariant, rather than being covariant (or even contravariant).

what you are looking for is something along these lines:

``````function myVFun{T <: A}(p::Vector{T},lambda::Integer)
return sum( [ f1(v) for v in p] )
end
``````

Basically you are defining a parametric function for every type that is a sub-type of A

1 Like

And I can call the function then with `myVFun(f)`, when `f::Vector{B}`?

Use a parameterized type this way:

``````import Base: length

abstract A{T}
type B{T} <: A{T}
value::Vector{T}
end

length{T}(x::B{T}) = length(x.value)

function myFunction{T}(x::B{T})
n = length(x)
s = "A vector of type Vector{\$T} and length \$n."
return s
end

myInts = B( [1,2,3] )
myChars = B( ['a', 'b', 'c', 'd'] )

myFunction(myInts)
myFunction(myChars)
``````

Running that displays

``````julia> myInts = B( [1,2,3] )
B{Int64}([1,2,3])

julia> myChars = B( ['a', 'b', 'c'] )
B{Char}(['a','b','c'])

julia> myFunction(myInts)
"A vector of type Vector{Int64} and length 3."

julia> myFunction(myChars)
"A vector of type Vector{Char} and length 4."
``````

Do you questions about how this example works?

You can have specialized handling for vectors of a given type:

``````# specialize the handling of Bs with Integer vectors
function myFunction{ T<:Integer }(x::B{T})
s = "Specialized Handling for Bs with Integer vectors"
return s
end
``````

now running the example displays

``````julia> myFunction(myChars)
"A vector of type Vector{Char} and length 3."

julia> myFunction(myInts)
"Specialized Handling for Bs with Integer vectors"
``````
2 Likes

Thanks @jsarnoff your example made the point very clear and even the specialization is neatly explained. The method dispatching now works.

Edit: And it even works for operator overloading in order to use the subtype constructor

``````+{B <: A}(a::T,b::T) = T(a.value+b.value)
``````

thats really neat!