Why do I get a type error when passing a dict with subtypes?

Hi,

I’m passing a dict to a constructor containing objects which are a subtype of the type expected and I get a type error on it:

ERROR: TypeError: in keyword argument res_input, expected Dict{BluePrint,Int64}, got a value of type Dict{ConsumableBluePrint,Int64}

ConsumableBluePrint is a subtype of BluePrint though.

abstract type Entity end

abstract type BluePrint end

struct ConsumableBluePrint <: BluePrint
    type_id::UUID
    name::String
    ConsumableBluePrint(name::String) = new(uuid4(), name)
end

struct ToolBluePrint <: BluePrint
    type_id::UUID
    name::String
    lifecycle::Restorable
    ToolBluePrint(name::String, lifecycle::Restorable = Restorable()) =
        new(uuid4(), name, lifecycle)
end

struct ProducerBluePrint <: BluePrint
    type_id::UUID
    name::String
    lifecycle::Restorable
    res_input::Dict{BluePrint,Int64} # Required input per batch
    output::Dict{BluePrint,Int64} # Output per batch. The BluePrint and the number of items per BluePrint.
    max_batches::Int64
    ProducerBluePrint(
        name::String,
        lifecycle::Restorable = Restorable();
        res_input = Dict(),
        output = Dict(),
        max_batches::Int = 1,
    ) = new(uuid4(), name, lifecycle, res_input, output, max_batches)
end

So, why do I get this error? And how can I fix it?

Thanks in advance,
Stef

Types in Julia are invariant wrt their parameters, more on that in the docs. That means, Sub <: Super does not imply T{Sub} <: T{Super}. If you need the concept of “Super and all it subtypes as a type parameter”, use T{<:Super} or T{S where S<:Super}

In your case, it seems that it’s better to work the other way: initialize your res_input and output with Dict{BluePrint, Int64}() or, if you use a comprehension, Dict{BluePrint, Int64}(k => v for (k, v) in itr).

4 Likes