I was playing around with vague constructors and I noticed some very interesting and useful behavior of arrays. I can use “subtype” notation in array constructors!
julia> S = Diagonal(randn(5))
5×5 Diagonal{Float64, Vector{Float64}}:
0.324104 ⋅ ⋅ ⋅ ⋅
⋅ -0.561848 ⋅ ⋅ ⋅
⋅ ⋅ 1.56105 ⋅ ⋅
⋅ ⋅ ⋅ -1.21263 ⋅
⋅ ⋅ ⋅ ⋅ 2.01912
julia> Array{<:Any,2}(S)
5×5 Matrix{Float64}:
0.324104 0.0 0.0 0.0 0.0
0.0 -0.561848 0.0 0.0 0.0
0.0 0.0 1.56105 0.0 0.0
0.0 0.0 0.0 -1.21263 0.0
0.0 0.0 0.0 0.0 2.01912
How can I make my own structs do this? For example, I have a type called Quantity:
struct Quantity{T<:Any,U<:AbstractUnitLike}
value :: T
units :: U
end
I would like to get this behaviour if I do something like what follows instead of getting this error:
Quantity{Float64, <:AffineUnits}(v, u)
ERROR: MethodError: no method matching (Quantity{Float64, <:AffineUnits})(::Float64, ::AffineUnits{Dimensions{FixedRational{Int32, 25200}}})
The type `Quantity{Float64, <:AffineUnits}` exists, but no method is defined for this combination of argument types when trying to construct it.
Stacktrace:
[1] top-level scope
@ REPL[20]:1
How do I define the behaviour of a broader class like
Quantity{Float64, <:AbstractUnits}(v, u)
without defining a whole bunch of methods?