# Understanding dispatch on types with nested type parameters and covariance

**URL:** https://discourse.julialang.org/t/understanding-dispatch-on-types-with-nested-type-parameters-and-covariance/24018
**Category:** General Usage
**Created:** [May 9, 2019, 8:46am UTC](https://discourse.julialang.org/t/understanding-dispatch-on-types-with-nested-type-parameters-and-covariance/24018 "2019-05-09T08:46:18Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![oschulz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oschulz/32/2998_2.png) [@oschulz](https://discourse.julialang.org/u/oschulz)
#### Post date: [May 9, 2019, 8:46am UTC](https://discourse.julialang.org/t/understanding-dispatch-on-types-with-nested-type-parameters-and-covariance/24018/1 "2019-05-09T08:46:18Z")

</div>

I feel it should be obvious, but I can’t figure it out. Why does this work:

```julia
julia> function foo(::Type{<:AbstractArray{<:Integer}})
julia> foo(AbstractArray{<:Signed})

```

But not this:

```julia
julia> function bar(::Type{<:AbstractArray{T}}) where {T<:Integer}
julia> bar(AbstractArray{<:Signed})

ERROR: MethodError: no method matching bar(::Type{AbstractArray{#s47,N} where N where #s47<:Signed})
Closest candidates are:
  bar(::Type{#s47} where #s47<:(AbstractArray{T<:Integer,N} where N)) where T<:Integer at REPL[3]:2

```

This works, however:

```julia
julia> bar(AbstractArray{Signed})

```

---

<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 9, 2019, 8:56am UTC](https://discourse.julialang.org/t/understanding-dispatch-on-types-with-nested-type-parameters-and-covariance/24018/2 "2019-05-09T08:56:38Z")

</div>

Do you really want to dispatch on the argument being a union type?

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [May 9, 2019, 9:24am UTC](https://discourse.julialang.org/t/understanding-dispatch-on-types-with-nested-type-parameters-and-covariance/24018/3 "2019-05-09T09:24:33Z")

</div>

Because

```julia
foo(::Type{<:AbstractArray{<:Integer}})

```

means

```julia
foo(::Type{<:AbstractArray{T} where T <: Integer})

```

---

<div class="post-metadata">

### Author: ![oschulz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oschulz/32/2998_2.png) [@oschulz](https://discourse.julialang.org/u/oschulz)
#### Post date: [May 9, 2019, 2:53pm UTC](https://discourse.julialang.org/t/understanding-dispatch-on-types-with-nested-type-parameters-and-covariance/24018/4 "2019-05-09T14:53:16Z")

</div>

> Do you really want to dispatch on the argument being a union type?

Actually yes, in this case. This was just a toy example, what’s actually provided is the a type to be read from data. So the user is supposed to just specify “I expect an array of integers” without giving the exact type.

---

<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 9, 2019, 3:06pm UTC](https://discourse.julialang.org/t/understanding-dispatch-on-types-with-nested-type-parameters-and-covariance/24018/5 "2019-05-09T15:06:10Z")

</div>

> [@oschulz](#):
>
> So the user is supposed to just specify “I expect an array of integers” without giving the exact type.

I am curious what the purpose of this is. It will not yield fast code when the type is abstract. Also, `AbstractArray{<:Integer}` will miss perfectly fine arrays of integers, such as

```julia
Any[1, 2, 3]

```

IMO well written Julia code should have results which are _invariant_ to container types, except for result container types (not values!) and of course speed. A function that works on a `Int[1, 2, 3]` should work on `Any[1, 2, 3]` or `Real[1, 2, 3]`, even if it is (significantly) slower.

---

<div class="post-metadata">

### Author: ![oschulz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oschulz/32/2998_2.png) [@oschulz](https://discourse.julialang.org/u/oschulz)
#### Post date: [May 9, 2019, 4:10pm UTC](https://discourse.julialang.org/t/understanding-dispatch-on-types-with-nested-type-parameters-and-covariance/24018/6 "2019-05-09T16:10:47Z")

</div>

> I am curious what the purpose of this is. It will not yield fast code when the type is abstract.

Definitely not - but I’m using it as a way for the user to express how some data is to be interpreted, semantically (data stored in HDF5). For example, is a matrix a matrix or a vector of vectors? Is an HDF5 group a table of columns? Semantics like that. So that dispatch is only run once every multi-megabytes, hence speed is not an issue.

I do have a workaround for this, I just wanted to understand what makes  
`foo(::Type{<:AbstractArray{<:Integer}})` different from `bar(::Type{<:AbstractArray{T}}) where {T<:Integer}` when it comes to dispatch. The method error does list bar as a candidate, and in color mode, not part of it is colored as doesn’t match. But why doesn’t it match? Mainly, I was curious about what I’m missing about dispatch and type system here (probably something obvious).

---

<div class="post-metadata">

### Author: ![oschulz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oschulz/32/2998_2.png) [@oschulz](https://discourse.julialang.org/u/oschulz)
#### Post date: [May 9, 2019, 4:11pm UTC](https://discourse.julialang.org/t/understanding-dispatch-on-types-with-nested-type-parameters-and-covariance/24018/7 "2019-05-09T16:11:24Z")

</div>

> [@kristoffer.carlsson](#):
>
> Because
> 
> ```julia
> foo(::Type{<:AbstractArray{<:Integer}})
> 
> ```
> 
> means
> 
> ```julia
> foo(::Type{<:AbstractArray{T} where T <: Integer})
> 
> ```

Sure, I know it’s not the same as `bar`, exactly. But why doesn’t dispatch find `bar`?

---

<div class="post-metadata">

### Author: ![jeff.bezanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff.bezanson/32/48_2.png) [@jeff.bezanson](https://discourse.julialang.org/u/jeff.bezanson)
#### Post date: [May 9, 2019, 7:59pm UTC](https://discourse.julialang.org/t/understanding-dispatch-on-types-with-nested-type-parameters-and-covariance/24018/8 "2019-05-09T19:59:29Z")

</div>

The `where T` outside the signature basically means there needs to be a specific T value, and `AbstractArray{<:Signed}` does not have any specific value for T in `AbstractArray{T}`.

---

<div class="post-metadata">

### Author: ![oschulz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oschulz/32/2998_2.png) [@oschulz](https://discourse.julialang.org/u/oschulz)
#### Post date: [May 10, 2019, 8:13am UTC](https://discourse.julialang.org/t/understanding-dispatch-on-types-with-nested-type-parameters-and-covariance/24018/9 "2019-05-10T08:13:34Z")

</div>

> The `where T` outside the signature basically means there needs to be a specific T value

Thanks, @jeff.bezanson ! I never realized that (like @Tamas_Papp suggested I normally try hard to keep my code type stable 😉 ) - good to know!
