I have the following snippet:
abstract type AbstractReaction end
abstract type AbstractSpecies end
abstract type AbstractRateLaw end
struct Species <: AbstractSpecies
name::Union{AbstractString,Symbol}
end
struct MassAction{T<:Real,S<:Integer} <: AbstractRateLaw
reactants::Union{Array{Tuple{AbstractSpecies,T},2},Dict{AbstractSpecies, T}}
rate_constant::T
T_dependence::S
end
The idea here is that the user can define some reactants and then use those reactants to construct a mass-action rate law. I am trying to make the field MassAction.reactants
general, so that the user can pass two different types to instantiate the struct. For example, let’s say I define some reactants and some parameters that should be use to construct the MassAction
rate law:
a = Species("A")
b = Species("B")
params_vec_float = [(a,1.0) (b,2.0)]
params_vec_int = [(a,1) (b,2)]
params_dict_float = Dict(a=>1.0, b=>2.0)
params_dict_int = Dict(a=>1, b=>2)
rate_law1 = MassAction{Float64,Bool}(params_vec_float,1.0,true)
Which leads to the following error:
ERROR: MethodError: Cannot `convert` an object of type
Matrix{Tuple{Species, Float64}} to an object of type
Union{Dict{AbstractSpecies, Float64}, Matrix{Tuple{AbstractSpecies, Float64}}}
Closest candidates are:
convert(::Type{T}, ::T) where T at Base.jl:61
Stacktrace:
[1] MassAction{Float64, Bool}(reactants::Matrix{Tuple{Species, Float64}}, rate_constant::Float64, T_dependence::Bool)
@ Main ~/dev/julia/ReactorSimulator.jl/src/kinetics.jl:11
[2] top-level scope
@ REPL[7]:1
Upon reading the documentation, I found out that two objects the equivalency I am trying to use does not work because of parametric type invariance
My question is: how can I modify the type definition of the field MassAction.reactants
so that any of the params_vec_float, params_vec_int, params_dict_float, params_dict_int
would work when trying to instantiate the struct MassAction
?