# Proper parametric subtyping of AbstractArray

**URL:** <https://discourse.julialang.org/t/proper-parametric-subtyping-of-abstractarray/38723>\
**Category:** General Usage\
**Tags:** parametric-types\
**Created:** [May 4, 2020, 7:32am UTC](https://discourse.julialang.org/t/proper-parametric-subtyping-of-abstractarray/38723 "2020-05-04T07:32:46Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![tlienart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tlienart/32/7640_2.png) [@tlienart](https://discourse.julialang.org/u/tlienart)\
**Post date:** [May 4, 2020, 7:32am UTC](https://discourse.julialang.org/t/proper-parametric-subtyping-of-abstractarray/38723/1 "2020-05-04T07:32:46Z")

</div>

I ended up banging my head against this yesterday, I guess I’m interested by both the _how to do this properly_ as well as the _why did the other ways not work_ in order to get better at this parametric type business.

**Aim:** have an object that’s a subtype of `AbstractVector` which keeps track of two things:

- a support (vector of, say, symbols) of length `c`
- an array of weights of size `n x c` (e.g. scores returned by a classifier)

so each “element” of the vector corresponds to a pair (support, weights) where support and weights have the same length `c`.

What I tried to express in a parametric way is that the support and the number of columns of the arrays are tied. So I tried:

```julia-repl
julia> struct Foo{W<:AbstractArray{<:Real, C}, S<:NTuple{C,Symbol}} where {C} <: AbstractVector
           weights::W
           support::S
       end
ERROR: syntax: invalid type signature
Stacktrace:
 [1] top-level scope at none:1

```

crap. (By the way that error message is a bit unhelpful.).

So I tried something simpler to try to build from there:

```julia-repl
julia> struct Foo{T, C} <: AbstractVector
           weights::Array{T,C}
           support::NTuple{C,Symbol}
       end
ERROR: invalid subtyping in definition of Foo
Stacktrace:
 [1] top-level scope at none:1

```

☹ after trying many more sillier variants and eventually coming to the conclusion that clearly I didn’t understand what I was doing, I decided to ask for help, so here I am, help!

PS: in the mean time I’m using something less constraining with an internal constructor that checks that dimensions match but it feels unsatisfactory.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [May 4, 2020, 7:59am UTC](https://discourse.julialang.org/t/proper-parametric-subtyping-of-abstractarray/38723/2 "2020-05-04T07:59:11Z")

</div>

I am not sure I understood the specs, but I am wondering if you are simply looking for

```julia
struct Foo{T,C,W<:AbstractArray{T,C},S<:NTuple{C,Symbol}} <: AbstractVector{T}
    weights::W
    support::S
end

```

Note

1. that parametric supertypes need parameters, eg

2. `struct`s cannot have an `UnionAll`/`where` clause _outside_ (what would it even mean?), so

These two are MWE for your error messages.

You may want to revisit the [types chapter of the manual](https://docs.julialang.org/en/v1/manual/types).

---

<div class="post-metadata">

**Author:** ![tlienart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tlienart/32/7640_2.png) [@tlienart](https://discourse.julialang.org/u/tlienart)\
**Post date:** [May 4, 2020, 8:59am UTC](https://discourse.julialang.org/t/proper-parametric-subtyping-of-abstractarray/38723/3 "2020-05-04T08:59:06Z")

</div>

Thanks Tamas, so I basically needed to add “C” as a free parameter (as opposed to that ill-placed “where” that you flagged), thanks a lot for that! (and fair enough for the sub typing needing parameter 👍 )

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [May 4, 2020, 9:32am UTC](https://discourse.julialang.org/t/proper-parametric-subtyping-of-abstractarray/38723/4 "2020-05-04T09:32:03Z")

</div>

> [@tlienart](#):
>
> an array of weights of size `n x c`  
> …  
> `weights::Array{T,C}`

These seem at odds. An `Array{T, C}` isn’t an `NxC` array, but a `C`-_dimensional_ array. It’s a bit unclear to me what you are going for, but are you confusing dimensions with sizes here?

> [@tlienart](#):
>
> What I tried to express in a parametric way is that the support and the number of columns of the arrays are tied.

The number of columns of an ordinary `Array` is not expressed in the type domain, you’ll have to use a different kind of array for that, for example a StaticArray. For ordinary `Array`s you’ll have to enforce it in the constructor.

---

<div class="post-metadata">

**Author:** ![tlienart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tlienart/32/7640_2.png) [@tlienart](https://discourse.julialang.org/u/tlienart)\
**Post date:** [May 4, 2020, 10:03am UTC](https://discourse.julialang.org/t/proper-parametric-subtyping-of-abstractarray/38723/5 "2020-05-04T10:03:02Z")

</div>

Yes I realise that my question was not asked properly but it was the answer I was looking for (I understand that array dimensions are not parametrised, my mistake for trying to write a simplified MWE), I guess what I would probably want is an `NTuple` of Vectors or indeed a StaticArrays. Thanks!
