I am currently stuck trying to get the benefits of mutable lists while maintaining type covariance logic.
Essentially I would like to be able to do the following:
abstract VTKData
typealias VTKDataGroup{T} Array{T<:VTKData, 1}
type VTKUnstructuredData <: VTKData
end
type VTKStructuredData <: VTKData
end
type VTKMultiblockData <: VTKData
blocks::VTKDataGroup{VTKData}
end
type VTKTimeSeriesData <: VTKData
data::VTKDataGroup{VTKData}
end
Additionally, I would like VTKMultiblockData to hold data from different VTKData subtypes while imposing a constraint on VTKTimeSeriesData to have the same VTKData subtype throughout the array.
Of course I am ommitting most of the fields. But the main point is that I want to be able to define generic behaviour on arrays of abstract types, that also applies to arrays of their subtypes without using tuple types, often with an additional homogeneity constraint. Is there any way to do this that does not involve tuple types, a ton of assertions, and/or metaprogramming?
Here is a little attempt that uses Union almost abusively and achieves homogeneity.
julia> isa([1,"a"], Union{Vector{Int},Vector{String}})
false
julia> isa(["a","a"], Union{Vector{Int},Vector{String}})
true
julia> isa([1,1], Union{Vector{Int},Vector{String}})
true
It also supports non-homogeneity only when types can be promoted to some common type, which kind of defeats the purpose of using Union.
julia> isa([1,2.], Vector{Union{Int,Float64}})
false
julia> isa([1,2], Vector{Int})
true
julia> isa([1,2.], Union{Vector{Int},Vector{Float64}})
true
julia> isa([1,2.], Vector{Float64})
true
julia> isa([1,2.], Vector{Int})
false
Here is another weird but related example that I don’t understand. So I would appreciate it if someone explains.
julia> typealias RealArray{T} Array{T<:Real,1}
Array{false,1}
julia> isa([1,2.],RealArray{Float64})
false