2

Given some complex object, e.g.:

> d = Dict(("a", "b")=>3, ("c", "d")=>2)
Dict{Tuple{String,String},Int64} with 2 entries:
  ("c","d") => 2
  ("a","b") => 3

I could check the type with:

> isa(d, Dict{Tuple{String, String},Int64})
true

But when I underspecify the Tuple type, it failed the check:

> isa(d, Dict{Tuple,Int64})
false

Is it possible to check for underspecified types in Julia? If so, how? If not, why?

alvas
  • 115,346
  • 109
  • 446
  • 738

2 Answers2

3

In Julia, dictionaries, like arrays, are invariant. For example, see this question on the concept as it applies to arrays.

This means that:

julia> Int <: Number
true

but,

julia> Vector{Int} <: Vector{Number}
false

and similarly,

julia> Dict{Int, String} <: Dict{Number, String}
false

However, note that Dict on its own is abstract, so

julia> Dict{Int, String} <: Dict
true

and in the code you provide,

julia> isa(d, Dict)
true

As far as I know, if you want to reason specifically about the pair of types in your dictionary, you will need to reference them explicitly. You can do this using keytype(d) and valtype(d). For example, from your question, note that

julia> keytype(d) <: Tuple
true

Of course, if your dictionary is passed into a function, then you can use Dict{T1, T2} in the function signature, and then just reason about T1 and T2...

EDIT: See @FengyangWang's answer for a neat little syntax shortcut being introduced in v0.6

Community
  • 1
  • 1
Colin T Bowers
  • 18,106
  • 8
  • 61
  • 89
1

In Julia 0.6 you can simply do

isa(d, Dict{<:Tuple, Int64})

which means a Dict with key type a subtype of Tuple, and value type Int64.

Note that Dict{Tuple, Int64} is not an "underspecified" type: it is a concrete type and can have instances. However, Dict{Tuple{String, String}, Int64} is not the same thing. The former is a type that accepts all tuples as keys, whereas the latter only accepts Tuple{String, String}. This is an example of parametric invariance.

Fengyang Wang
  • 11,901
  • 2
  • 38
  • 67