# Parametric types with parameters left unspecified as struct fields

Suppose I have a mutable struct with a field used to store a sparse matrix, e.g.

``````mutable struct myStruct{Tv<:Number,Ti<:Integer}
A::SparseMatrixCSC{Tv,Ti}
end
``````

This works as expected for various combinations of `Tv` and `Ti`. Now suppose I was lazy, as I was yesterday and instead I defined

``````mutable struct mySimpleStruct
A::SparseMatrixCSC
end
``````

I understand that this is bad practice because the actual concrete type of `A` in instances of `mySimpleStruct` can’t be inferred. However, I had assumed that the `mySimpleStruct` construction would still allow me to work with any type of sparse matrix. However, I’ve observed the following behaviour, which I don’t understand:

``````>A = sprandn(10,10,0.1)
>A = convert(SparseMatrixCSC{Float64,Int32},A)
>mySimpleStruct(A)

mySimpleStruct
A → 10×10 SparseMatrixCSC{Float64,Int64} with 7 stored entries
``````

As you can see, in storing my `SparseMatrixCSC{Float64,Int32}` matrix in a `mySimpleStruct`, the non-zero index storage was converted from `Vector{Int32}` to `Vector{Int64}`. I would have thought that specifying a field of a struct as just `SparseMatrixCSC` would allow it to store any type of sparse matrix but this doesn’t seem to be the case. Anyone know why the type conversion shown above is happening? I would have thought `SparseMatrixCSC` would behave like an abstract type with all the various concrete types `SparseMatrixCSC{Tv,Ti}` being subtypes. Why is that not the case? `SparseMatrixCSC{Float64,Int32} <: SparseMatrixCSC` returns `true`.

Thanks, Patrick

Constructing a `struct` (with all of its parameters specified) or storing an element will, as I understand it, implicitly call `convert(<the type of the field>, <the value>)`. If `x isa T`, then `convert(T, x)` is generally a no-op so you don’t see this behavior. However, `SparseMatrixCSC` is a bit odd in that respect:

``````julia> A = sprandn(10, 10, 0.1);

julia> A32 = convert(SparseMatrixCSC{Float64, Int32}, A);

julia> typeof(A32)
SparseMatrixCSC{Float64,Int32}

julia> typeof(convert(SparseMatrixCSC, A32))
SparseMatrixCSC{Float64,Int64}
``````

this happens because of a method in `sparsematrix.jl`:

``````julia> @edit convert(SparseMatrixCSC, A32)

# should show the following in your editor:
# convert(::Type{SparseMatrixCSC}, M::AbstractMatrix{Tv}) where {Tv} = convert(SparseMatrixCSC{Tv,Int}, M)
``````

Oh, interesting. That explains it. Thanks a lot.

Arguably this is a bug. Probably this should be defined

``````convert(::Type{SparseMatrixCSC}, M::SparseMatrixCSC)  = M
``````