Vector of vectors with floats: Type confusion

I have a vector of vectors vv. Each vector v in vv is of type Vector{Float32}:

julia> unique(typeof.(vv))

1-element Vector{DataType}:
Vector{Float32} (alias for Array{Float32, 1})

However,

julia> typeof(vv)
Vector{Vector} (alias for Array{Array{T, 1} where T, 1})

I would have expected the type of vv to be Vector{Vector{Float32}}. In fact, I’m passing vv as argument to a function that expects an argument type Vector{<:Vector{Float32}} (of course I’m getting an error).

This behavior is strange. Why is the type of vv not Vector{Vector{Float32}}?

1 Like

it can depend on how you’ve constructed vv

julia> vv_any = []; push!(vv_any, [1.0f0]);

julia> typeof(vv_any)
Vector{Any} (alias for Array{Any, 1})


julia> vv_f32 = Vector{Float32}[[1.0f0], [2.0f0]];

julia> typeof(vv_f32)
Vector{Vector{Float32}} (alias for Array{Array{Float32, 1}, 1})


julia> foo() = rand() < 0.5 ? Float32[1.0f0] : String[] # not type-stable

julia> vv_typed = [foo() for _ ∈ 1:10];

julia> typeof(vv_typed)
Vector{Vector} (alias for Array{Array{T, 1} where T, 1})

It may clear things up to think of variable bindings having types, not just variable values (where the type of the binding must be a supertype of the type of the value it points to)

note that above, both vv_any and vv_typed are convertible to the type you want via convert(Vector{Vector{Float32}}, _)

5 Likes

A clarifying answer. The problem indeed came from the construction of vv. Thanks!

I don’t understand what you mean by this. The only thing going on here, surely, is that there’s an array which is not parameterize sufficiently narrowly, that is, entirely to do with the type of the value. What does the binding have to do with this?

it’s just a mental model that is probably not entirely technically accurate. all I mean is that the type of the variable is not necessarily equal to the “actual” most concrete type possible for the data that variable points to.