# Defining inner constructor with parametric types in Julia

**Shuvomoy Das Gupta**

*January 12, 2021*

Suppose we define the following parametric type in Julia.

```
abstract type CombinatorialProblem end
struct BinIntOptSF{V <: AbstractVector{<: Real}, M <: AbstractMatrix{<: Real}} <: CombinatorialProblem # means the concrete type BinIntOptSF is a subtype of the abstract type CombinatorialProblem
c::V
A::M
b::V
end
```

This is a parametric type. We can create an instance of this type as follows.

```
m = 4
n = 5
c = randn(n)
A = randn(m,n)
b = randn(m)
sf_bin_int_opt = BinIntOptSF(c, A, b)
```

Now suppose, we want to enforce the following check in an instance of the type: `A`

must have number of rows less than or equal to number of columns, number of rows of `A`

is equal number of entries in `b`

, and number of columns of `A`

is equal to the number of entries in `c`

.

In this case we can enforce the check by writing the following inner constructor for the parametric type.

```
struct BinIntOptSF2{V <: AbstractVector{<: Real}, M <: AbstractMatrix{<: Real}} <: CombinatorialProblem
c::V
A::M
b::V
# Inner constructor
# -----------------
function BinIntOptSF2{V,M}(c::V, A::M, b::V) where {V <: AbstractVector{<: Real}, M <: AbstractMatrix{<: Real}}
if size(A,1) != size(b,1)
error("A and b have incompatible direction")
end
if size(A,1) > size(A,2)
error("A must have number of row less than or equal to number of columns")
end
if size(A,2) != size(c,1)
error("A and c have incompatible dimension")
end
new{V, M}(c,A,b)
end
# Writing the inner constructor above is going to replace the default constructor that is automatically defined by Julia. This may cause slight inconvenience, as we have to instantiate by running: bin_opt_instance = BinIntOptSF2{.,.}(...). Fortunately we can avoid this by adding the following line.
# Ensuring the one shot instantiation
# -----------------------------------
BinIntOptSF2(c::V, A::M, b::V) where {V <: AbstractVector{<: Real}, M <: AbstractMatrix{<: Real}} = BinIntOptSF2{V,M}(c,A,b)
# We need to add this line so that we can instantiate by the convenient: bin_opt_instance = BinIntOptSF2(.). If we do not add this line, but call BinIntOptSF2(.), then we will get an error "No method matching...".
end
```

Let us instantiate the type above.

`sf_bin_int_opt_2 = BinIntOptSF2(c, A, b)`

© Shuvomoy Das Gupta. Last modified: September 12, 2022. Website built with Franklin.jl and the Julia programming language.