mauro3/Parameters.jl

reconstruct parametric type: allow type override?

daviehh opened this issue · 2 comments

Consider a parametric struct where one field can be a floating-point vector or array:

@with_kw struct Foo{T <: VecOrMat{Float64}}
    h::T
    x::Float64
    y::Float64
    z::Float64
end

first, make one object where h is a vector,

a = Foo{Vector{Float64}}(h=[1,2,3], x=1, y=2, z=3)

Then, if one want to have another object b where h is now a matrix and all other fields are the same as a, the expression b = Foo(a; h=[1 2;3 4]) does not work since Foo{Matrix{Float64}} is a different type:

MethodError: no method matching Array{Float64,1}(::Array{Int64,2})

How about adding another optional argument to reconstruct to allow for type overriding? WIP changes daviehh@6ff721b

@daviehh: Sorry for the long wait. I re-implemented your idea in PR #143. Looks like

julia> struct B{T}
          a::T
          b
       end

julia> a = B(sin, 1)
B{typeof(sin)}(sin, 1)

julia> reconstruct(B, a, a=cos) # note reconstruct(a, a=cos) errors!
B{typeof(cos)}(cos, 1)

I will merge the PR soon. Does this look good to you?

@mauro3 Thanks for the nice implementation, it works nicely! For the example/docstring, maybe it would be better if the example variable is named differently, e.g. x = B(sin, 1)? I understand the first a in reconstruct(B, a, a=cos) refers to the variable a of type B while the second a in a=cos refers to the field a in the struct B, but having two a in the example reconstruct(B, a, a=cos) might be confusion to new users/people just glancing through?

Thanks again for the code!