without luck trying TypeSortedCollections
(until now), I think of a recursive solution to due with heterogeneous container.
Let’s phase the problem first: there’s a parametric type MyParamType
, and a Vector{MyParamType}
. Noted that this vector is heterogeneous.
struct MyParamType{T<:Real}
x::T
end
heter = [MyParamType(1), MyParamType(2.2), MyParamType(3), MyParamType(4.4) ]
julia> heter = [MyParamType(1), MyParamType(2.2), MyParamType(3), MyParamType(4.4) ]
4-element Array{MyParamType,1}:
MyParamType{Int64}(1)
MyParamType{Float64}(2.2)
MyParamType{Int64}(3)
MyParamType{Float64}(4.4)
now, a function that directly accesses the element of this vector would cause warntype:
function f(a::Vector{MyParamType} )
for i in 1:length(a)
println(a[i].x)
end
end
julia> f(heter)
1
2.2
3
4.4
julia> @code_warntype f(heter)
│ %15 = (Base.arrayref)(true, a, %13)::MyParamType
│ %16 = (Base.getfield)(%15, :x)::Real
now, define a new parametric type for recursion:
struct Recursive{S, T}
part1::S
part2::T
end
function Recursive(v::Vector{MyParamType})
if length(v) == 2
return Recursive(v[1], v[2])
else
return Recursive(v[1], Recursive(v[2:end]) )
end
end
then pass the heterogeneous vector into the outer constructor to create the recursion object:
recur = Recursive(heter)
julia> recur.part1
MyParamType{Int64}(1)
julia> recur.part2
Recursive{MyParamType{Float64},Recursive{MyParamType{Int64},MyParamType{Float64}}}(MyParamType{Float64}(2.2), Recursive{MyParamType{Int64},MyParamType{Float64}}(MyParamType{Int64}(3), MyParamType{Float64}(4.4)))
julia> recur.part2.part1
MyParamType{Float64}(2.2)
julia> recur.part2.part2
Recursive{MyParamType{Int64},MyParamType{Float64}}(MyParamType{Int64}(3), MyParamType{Float64}(4.4))
julia> recur.part2.part2.part1
MyParamType{Int64}(3)
julia> recur.part2.part2.part2
MyParamType{Float64}(4.4)
(note that the call of outer constructor is itself warntype. But it’s fine.)
now, the (time-sensitive) function f()
is re-written as g()
in a recursive manner:
function g(b::Recursive)
println(b.part1.x)
if b.part2 isa MyParamType
println(b.part2.x)
else
g(b.part2)
end
end
julia> g(recur)
1
2.2
3
4.4
@code_warntype g(recur) # fine :D
finally! there’s no warntype!!!
any comments?