Search code examples
dictionarytypestuplesjuliatypechecking

Underspecification when checking complex types in Julia


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?


Solution

  • 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