# Struct constructors with partial types

**URL:** <https://discourse.julialang.org/t/struct-constructors-with-partial-types/79760>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [April 21, 2022, 2:08am UTC](https://discourse.julialang.org/t/struct-constructors-with-partial-types/79760 "2022-04-21T02:08:51Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![tictaccat](https://avatars.discourse-cdn.com/v4/letter/t/9f8e36/32.png) [@tictaccat](https://discourse.julialang.org/u/tictaccat)\
**Post date:** [April 21, 2022, 2:08am UTC](https://discourse.julialang.org/t/struct-constructors-with-partial-types/79760/1 "2022-04-21T02:08:51Z")

</div>

Suppose I make a struct as follows

```julia
struct MyStruct{A,B}
       x::A
       y::B
end

```

Why is it that the following two constructions work:

```julia
julia> MyStruct(3,4)
MyStruct{Int64, Int64}(3, 4)
julia> MyStruct{Int64, Int64}(3,4)
MyStruct{Int64, Int64}(3, 4)

```

but this one fails?

```julia
julia> MyStruct{Int64}(3,4)
ERROR: MethodError: no method matching (MyStruct{Int64, B} where B)(::Int64, ::Int64)

```

Intuitively, `B` should just match `Int64` in `MyStruct{Int64, B} where B` and things should work, just like both types get matched in `MyStruct(3,4)`, which is equivalent to `(MyStruct{A,B} where {A,B})(3,4)`? But I must be misunderstanding something because that is not happening, I would greatly appreciate some clarity!

---

<div class="post-metadata">

**Author:** ![Jollywatt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jollywatt/32/202198_2.png) [@Jollywatt](https://discourse.julialang.org/u/Jollywatt)\
**Post date:** [April 21, 2022, 2:30am UTC](https://discourse.julialang.org/t/struct-constructors-with-partial-types/79760/2 "2022-04-21T02:30:06Z")

</div>

From the docs about [composite types](https://docs.julialang.org/en/v1/manual/types/#Composite-Types):

> Two constructors are generated automatically (these are called _default constructors_ ). One accepts any arguments and calls [`convert`](https://docs.julialang.org/en/v1/base/base/#Base.convert) to convert them to the types of the fields, and the other accepts arguments that match the field types exactly.

These two default constructors are `MyStruct(x,y)` and `MyStruct{A,B}(x,y)`.

You can add your missing constructor by defining it afterwards:

```julia
struct MyStruct{A,B}
       x::A
       y::B
end
MyStruct{A}(x, y) where A = MyStruct(convert(A, x), y)

```

Alternatively, you can opt-out of having the two default constructors by defining [inner constructors](https://docs.julialang.org/en/v1/manual/constructors/#man-inner-constructor-methods).

```julia
struct MyStruct{A,B}
       x::A
       y::B
       MyStruct{A}(x, y) where A = MyStruct(convert(A, x), y)
end

```

Now, there is only the one constructor.

---

<div class="post-metadata">

**Author:** ![tictaccat](https://avatars.discourse-cdn.com/v4/letter/t/9f8e36/32.png) [@tictaccat](https://discourse.julialang.org/u/tictaccat)\
**Post date:** [April 21, 2022, 2:37am UTC](https://discourse.julialang.org/t/struct-constructors-with-partial-types/79760/3 "2022-04-21T02:37:39Z")

</div>

> [@tictaccat](#):
>
> `no method matching (MyStruct{Int64, B} where B)`

That makes sense. But I guess I’m still a little confused by the error message. Taken literally, there _is_ a method matching `MyStruct{Int64, B} where B`, which is `MyStruct{Int64, Int64}`, so what does that error message mean?

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [April 21, 2022, 5:41am UTC](https://discourse.julialang.org/t/struct-constructors-with-partial-types/79760/4 "2022-04-21T05:41:41Z")

</div>

> [@tictaccat](#):
>
> Taken literally, there _is_ a method matching `MyStruct{Int64, B} where B` , which is `MyStruct{Int64, Int64}` , so what does that error message mean?

How does that match? The first has an unbound type variable, which could be any type, while the latter requires that second type to be `Int`.
