# Vector of partially concrete parametric types

**URL:** <https://discourse.julialang.org/t/vector-of-partially-concrete-parametric-types/12795>\
**Category:** General Usage\
**Created:** [August 1, 2018, 4:50pm UTC](https://discourse.julialang.org/t/vector-of-partially-concrete-parametric-types/12795 "2018-08-01T16:50:35Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![dawbarton](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dawbarton/32/215461_2.png) [@dawbarton](https://discourse.julialang.org/u/dawbarton)\
**Post date:** [August 1, 2018, 4:50pm UTC](https://discourse.julialang.org/t/vector-of-partially-concrete-parametric-types/12795/1 "2018-08-01T16:50:35Z")

</div>

I thought I understood the `where` syntax but apparently I don’t. I have a parameterised structure along the lines of

```julia
struct MyStruct{T <: Number, F}
    u::Vector{T}
    f::F
end

```

and I’d like to have a vector of these structures such that the underlying numerical type is the same but the `f` field can be different (it’s a function). For example

```julia
v1 = MyStruct([1.0], sin)
v2 = MyStruct([2.0], cos)
v = [v1, v2]

```

In this case, as I understand it, the appropriate type signature is `Vector{MyStruct{T, F} where F} where T` and, as desired,

```julia
v isa Vector{MyStruct{T, F} where F} where T == true

```

However, if I just have a single element in the vector

```julia
vv = [v1]
vv isa Vector{MyStruct{T, F} where F} where T == false

```

but I don’t understand why.

I’d like to be able to handle both these cases. Is there a type signature that can handle both? (I know I can use a union with `Vector{MyStruct{T, F}} where {T, F}` but I was expecting the `where` syntax to be able to handle this directly.)

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [August 1, 2018, 5:17pm UTC](https://discourse.julialang.org/t/vector-of-partially-concrete-parametric-types/12795/2 "2018-08-01T17:17:36Z")

</div>

A `Vector{MyStruct{T, F} where F} where T` has an element type which allows potentially different `F`s for each element. When you do `[v1]` you’re instead getting `Vector{MyStruct{Float64, typeof(sin)}}` which has an element type which allows only that exact type. Those two `Vector` types are actually different types in Julia (because they have different element types).

Instead, you probably want, roughly, “A vector whose element type is some subtype of `MyStruct{T, F} where F`”. You can write that as:

```julia
Vector{M} where {T, M <: (MyStruct{T, F} where F)}

```

or, more simply, since you can leave off trailing type parameters:

```julia
Vector{M} where {T, M <: MyStruct{T}}

```

or, even more simply (and the style I’d suggest):

```julia
Vector{<:MyStruct{T}} where T

```

For more info, see the discussion of covariant vs. invariant types here: [https://docs.julialang.org/en/stable/manual/types/index.html#Parametric-Composite-Types-1](https://docs.julialang.org/en/stable/manual/types/index.html#Parametric-Composite-Types-1)

---

<div class="post-metadata">

**Author:** ![dawbarton](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dawbarton/32/215461_2.png) [@dawbarton](https://discourse.julialang.org/u/dawbarton)\
**Post date:** [August 1, 2018, 7:01pm UTC](https://discourse.julialang.org/t/vector-of-partially-concrete-parametric-types/12795/3 "2018-08-01T19:01:16Z")

</div>

> [@rdeits](#):
>
> A vector whose element type is some subtype of `MyStruct{T, F} where F`

As soon as you said this it became obvious what I was doing wrong. Thanks!

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [August 1, 2018, 8:50pm UTC](https://discourse.julialang.org/t/vector-of-partially-concrete-parametric-types/12795/4 "2018-08-01T20:50:42Z")

</div>

Will this actually be any better (in terms of performance) than just defining the type as

```julia
struct MyStruct{T <: Number}
    u::Vector{T}
    f::Function
end

```

though?

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [August 1, 2018, 8:59pm UTC](https://discourse.julialang.org/t/vector-of-partially-concrete-parametric-types/12795/5 "2018-08-01T20:59:53Z")

</div>

Yup, it will actually be better. `::Function` is an abstract type, so access to the `f` field would be type-unstable in that case. Of course, this may not actually matter much, depending on how that field is used, so it’s always worth benchmarking to be sure.

---

<div class="post-metadata">

**Author:** ![dawbarton](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dawbarton/32/215461_2.png) [@dawbarton](https://discourse.julialang.org/u/dawbarton)\
**Post date:** [August 1, 2018, 9:16pm UTC](https://discourse.julialang.org/t/vector-of-partially-concrete-parametric-types/12795/6 "2018-08-01T21:16:20Z")

</div>

In this case it’s going to be in a hot loop where performance is critical hence going for the parameterized form. (Though by the time it hits the hot loop it’s also been unpacked into a tuple with some `@generated` magic to avoid dynamic dispatch entirely. The vector form is for user convenience as the problem is sequentially constructed.)

Also, I quite like the convenience of being able to use arbitrary callables (e.g. callable structs), which aren’t subtypes of Function, as well as regular functions.
