# How to define an overload constructor across an abstract type?

**URL:** <https://discourse.julialang.org/t/how-to-define-an-overload-constructor-across-an-abstract-type/114535>\
**Category:** General Usage\
**Tags:** question\
**Created:** [May 21, 2024, 11:40pm UTC](https://discourse.julialang.org/t/how-to-define-an-overload-constructor-across-an-abstract-type/114535 "2024-05-21T23:40:32Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![lpz18](https://avatars.discourse-cdn.com/v4/letter/l/ec9cab/32.png) [@lpz18](https://discourse.julialang.org/u/lpz18)\
**Post date:** [May 21, 2024, 11:40pm UTC](https://discourse.julialang.org/t/how-to-define-an-overload-constructor-across-an-abstract-type/114535/1 "2024-05-21T23:40:32Z")

</div>

I have various structs of parameters that I am using for things like running ODEs and least squares optimizations, i.e.:

```julia
abstract type model_A end

struct params1 <: model_A
    a::Float64
end

struct params2 <: model_A
    a::Float64
    b::Float64
end

```

I have a utility function that lets my generate different parameter sets as I run optimizations or etc:

```julia
function range_of_model_parameters(
    model_type::Type{T}, args...
) where {T <: model_A}
    return vec([T(param_set...) for param_set in Iterators.product(args...)])
end

# example
p2 = range_of_model_parameters(params2, [1.0,2.1], 3)

```

I would like to be able to define a new constructor that applies to all the `model_A` types, such that I could run

```julia
p2 = params2([1.0, 2.1], 3)
p1 = params1([3.2, 5.6])
...

```

after only one definition of the constructor for the abstract type.

Any ideas on how to do this?

P.S. the reason I want to do this is because I need to re-define the parameter struct for each computation of the objective function when I optimize over a given parameter. Since the solvers are vectorized, when I re-define the struct the objective function is trying to pass in a vector of parameters and I get a type error. So it would be nice to have a method that automatically accepts the vector of parameters without having to redefine this for each argument and each concrete struct type

---

<div class="post-metadata">

**Author:** ![matthias314](https://avatars.discourse-cdn.com/v4/letter/m/a88e4f/32.png) [@matthias314](https://discourse.julialang.org/u/matthias314)\
**Post date:** [May 22, 2024, 1:34am UTC](https://discourse.julialang.org/t/how-to-define-an-overload-constructor-across-an-abstract-type/114535/2 "2024-05-22T01:34:27Z")

</div>

You could do something like the following:

```julia
abstract type model_A end

struct params1 <: model_A
    a::Float64
    params1(a::Number) = new(a)
end

struct params2 <: model_A
    a::Float64
    b::Float64
    params2(a::Number, b::Number) = new(a, b)
end

function (::Type{P})(args...) where P <: model_A
    [P(params...) for params in Iterators.product(args...)]
end

```

Then you get

```julia
julia> params1([1.0, 2.1])
2-element Vector{params1}:
 params1(1.0)
 params1(2.1)

julia> params2([1.0, 2.1], 3)
2-element Vector{params2}:
 params2(1.0, 3.0)
 params2(2.1, 3.0)

```

The inner constructor for each concrete type is needed to resolve method ambiguities.
