If

```
Int64 <: Real
```

is true, and I presume Julia follows normal function typing rules (for dicts) where the “return” type can be more specific than indicated by the type annotation, why isn’t the following true?

```
Dict(:x=>[1,2], :y=>[1,2]) isa Dict{Symbol, Array{<:Real, 1}}
```

Do I need to do something like:

```
Dict(:x=>[1,2], :y=>[1,2]) isa <:Dict{Symbol, Array{Real, 1}}
```

to ‘ask the question’ properly?

Welcome!

In Julia, type parameters are invariant. So even though `Int <: Real`

it is *not true* that `Array{Int} <: Array{Real}`

.Your use-case is just another example of such type invariance.

```
julia> Int <: Real
true
julia> Array{Int} <: Array{Real}
false
```

You can read more about types here

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

1 Like

What is happening here?

```
julia> [1,2] isa Array{<:Real,1}
true
```

and here?

```
julia> Array{Int} <: Array{<:Real}
true
```

Your last piece of code is equivalent to checking

```
julia> Array{Int} <: Array{T} where {T <: Real}
true
```

The RHS is the set of all types of the form `Array{T} where {T<:Real}`

. So, an element that belongs to `Array{Int}`

is also an element of `Array{T} where {T<:Real}`

. An element that belongs to `Array{Float64}`

is also an element of `Array{T} where {T<:Real}`

and so on

```
julia> Array{Float64} <: Array{T} where {T <: Real}
true
```

1 Like

So it seems like I can get the kind of type variance behavior that I intuitively want to use – returning to the original question, why doesn’t this “hack” work for the more complex type? :

```
julia> Dict{Symbol, Array{Int,1}} <: Dict{Symbol, Array{<:Real, 1}}
false
```

You need

```
julia> Dict{Symbol, Array{Int,1}} <: Dict{R, Array{T, 1}} where {R, T}
true
```

Thanks!

I see that

```
julia> Dict{Symbol, Array{Int,1}} <: Dict{Symbol, Array{T, 1}} where {T <: Real}
true
```

also works.

Is the way I am doing this not the “Julian” way to do things?

This is also fine and depends on whether you want to use a fixed type or its subset. What I wrote is slightly more generic because you can replace `R`

with any subtype of `Symbol.`

This is what you are doing with `Array{T, 1} where {T<:Real}`

as well. You are allowing the code to compile for a subtype of `Real`

so you have flexibility in that you can pass a subtype of `Real`

in place of `T`

like so

```
julia> Dict{Symbol, Array{Int,1}} <: Dict{Symbol, Array{T, 1}} where {T <: Real}
true
julia> Dict{Symbol, Array{Float64,1}} <: Dict{Symbol, Array{T, 1}} where {T <: Real}
true
```

There is nothing non-Julian in what you did but I like to keep my code as generic as possible Notice that keeping the code like `Array{T, 1} where {T<:Real}`

has no runtime penalty.

1 Like