I would like to use a subtype of a function parameter in my function definition. Is this possible? For example, I would like to write something like:
g{T1, T2<:T1}(x::T1, y::T2) = x + y
So that g
will be defined for any x::T1
and any y
that is a subtype of T1
. Obviously, if I knew, for example, that T1
would always be Number
, then I could write g{T<:Number}(x::Number, y::T) = x + y
and this would work fine. But this question is for cases where T1
is not known until run-time.
Read on if you're wondering why I would want to do this:
A full description of what I'm trying to do would be a bit cumbersome, but what follows is a simplified example.
I have a parameterised type, and a simple method defined over that type:
type MyVectorType{T}
x::Vector{T}
end
f1!{T}(m::MyVectorType{T}, xNew::T) = (m.x[1] = xNew)
I also have another type, with an abstract super-type defined as follows
abstract MyAbstract
type MyType <: MyAbstract ; end
I create an instance of MyVectorType
with vector element type set to MyAbstract
using:
m1 = MyVectorType(Array(MyAbstract, 1))
I now want to place an instance of MyType
in MyVectorType
. I can do this, since MyType <: MyAbstract
. However, I can't do this with f1!
, since the function definition means that xNew
must be of type T
, and T
will be MyAbstract
, not MyType
.
The two solutions I can think of to this problem are:
f2!(m::MyVectorType, xNew) = (m.x[1] = xNew)
f3!{T1, T2}(m::MyVectorType{T1}, xNew::T2) = T2 <: T1 ? (m.x[1] = xNew) : error("Oh dear!")
The first is essentially a duck-typing solution. The second performs the appropriate error check in the first step.
Which is preferred? Or is there a third, better solution I am not aware of?
See Question&Answers more detail:
os