# Type definition

**URL:** <https://discourse.julialang.org/t/type-definition/17027>\
**Category:** General Usage\
**Tags:** type, parametric-types\
**Created:** [October 31, 2018, 9:23pm UTC](https://discourse.julialang.org/t/type-definition/17027 "2018-10-31T21:23:25Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![jackf](https://avatars.discourse-cdn.com/v4/letter/j/b4bc9f/32.png) [@jackf](https://discourse.julialang.org/u/jackf)\
**Post date:** [October 31, 2018, 9:23pm UTC](https://discourse.julialang.org/t/type-definition/17027/1 "2018-10-31T21:23:26Z")

</div>

I’m trying to express a type where the field container types are all identical, but their element type varies. I have tried a few things but can’t crack it:

```julia
julia> struct MyType1{V <: AbstractVector}
          a::V{Int64}
          b::V{Float64}
      end
ERROR: TypeError: in Type{...} expression, expected UnionAll, got TypeVar

julia> struct MyType8{FV<:V{Float64}, IV <: V{Int64} where V <: AbstractVector}
           a::IV
           b::FV
       end
ERROR: UndefVarError: V not defined

```

Some help would be great please! - assuming this is possible to express at all.

---

<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:** [October 31, 2018, 9:59pm UTC](https://discourse.julialang.org/t/type-definition/17027/2 "2018-10-31T21:59:20Z")

</div>

I don’t think this is possible in Julia. You can, however, always check some condition on the type parameters inside an inner constructor. Or you can just leave FV and IV as potentially different kinds of AbstractArray. Perhaps it’s worth considering why you need them to actually be instances of the same parametric type V? For example, would it be enough to just check that they have the same axes or indices inside the inner constructor?

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [November 1, 2018, 12:09am UTC](https://discourse.julialang.org/t/type-definition/17027/3 "2018-11-01T00:09:20Z")

</div>

Yeah I don’t think so either.

For fun, I tried the following. So you want:

1. `V <: AbstractVector`
2. `IV <: AbstractVector{Int}`
3. `IV <: V`
4. `FV <: AbstractVector{Float64}`
5. `FV <: V`

(You probably also want `IV` and `FV` to be concrete types, but that’s another problem.) Unfortunately, you can only place constraints on a type parameter when you define it. But I thought maybe you could introduce ‘slack’ type variables `IS` and `FS`, drop constraints 3 and 5, and instead add `IV <: IS <: V` and `FV <: FS <: V`, as in:

```julia
struct MyType8{V<:AbstractVector, IV<:AbstractVector{Int}, FV<:AbstractVector{Float64}, IV<:IS<:V, FV<:FS<:V}
    a::IV
    b::FV
end

```

But you can’t actually construct this type, I believe, since even with this simpler version:

```julia
struct Foo{L, U, L<:T<:U}
end

```

Calling `Foo{Union{}, Any, Vector{Float64}}()` results in

```julia
UndefVarError: T not defined

```

even though `Union{} <: Vector{Float64} <: Any`.

---

<div class="post-metadata">

**Author:** ![jackf](https://avatars.discourse-cdn.com/v4/letter/j/b4bc9f/32.png) [@jackf](https://discourse.julialang.org/u/jackf)\
**Post date:** [November 1, 2018, 12:54am UTC](https://discourse.julialang.org/t/type-definition/17027/4 "2018-11-01T00:54:43Z")

</div>

Thanks both, makes sense.

The motivation was really just convenience. In reality, there are a dozen or so fields, all vectors of a few handful of element types. The structs would be created in a few ways, some of them coming from copied arrays (`V == Vector`), some of them coming from views (`V == SubArray{...}`) + some maybe whacky `ReinterpretedArrays` etc. I didn’t want to sacrifice later performance by unifying them all to AbstractVector. Without being able to do what we discussed above, the alternative is to just have a type parameter per field, or at least per element type. Slightly longer to write - that is all.
