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!