Hey everyone, could someone explain this subtyping behavior to me?

It does not seem intuitive to me.

```
Array{T where T} <: AbstractArray{T where T} # true
Array{Array{T where T}} <: AbstractArray{Array{T where T}} # also true
Array{Array{T where T}} <: AbstractArray{AbstractArray{T where T}} # false
```

I’m wondering why the last expression evaluates to false.

Thanks in advance!

To elaborate a bit more, if` x <: y`

then in general `Point{x} <: Point{y}`

may not always be true.

To begin, your first and second example work because `Array <: AbstractArray`

and what you are passing inside `{}`

are exactly the same i.e. in the second example, you are declaring `x = Array{T where T}`

and `y = Array{T where T}`

and then checking if ` Array{x} <: AbstractArray{y}`

is true. However, since `x = y`

this is equivalent to checking if `Array{x} <: AbstractArray{x}`

is true, which it is since `Array <: AbstractArray`

. Similarly, for the first example. The first and second examples basically say that any `Array`

can be represented as an `AbstractArray.`

```
julia> Array{Float64} <: AbstractArray{Float64}
true
```

Note that what you’ve done in your first and second examples is completely different from the following

because you are passing exactly the same types (unlike, subtypes which are passed below) inside `{}`

.

```
julia> Float64 <: Real
true
julia> Array{Float64} <: AbstractArray{Real}
false
julia> Array{Float64} <: Array{Real}
false
```

Now, as may be apparent from the previous example, the behavior manifested by the first and second examples need not hold if what you are passing inside `{}`

changes as it does in the third example. In fact, the third expression won’t even evaluate to true if I set `Point = Array`

on both sides of the equation i.e.

```
julia> Array{T where T} <: AbstractArray{T where T}
true
julia> Array{Array{T where T}} <: Array{AbstractArray{T where T}}
false
```

This behavior is consistent with the documentation below.

https://docs.julialang.org/en/v1/manual/types/index.html#Parametric-Types-1

Here is a more formal treatment of what’s meant by covariant, contravariant and invariant subtyping

https://eli.thegreenplace.net/2018/covariance-and-contravariance-in-subtyping/