# Typing functions arguments representing tuples of custom structs

**URL:** <https://discourse.julialang.org/t/typing-functions-arguments-representing-tuples-of-custom-structs/66395>\
**Category:** General Usage\
**Tags:** question, type, tuple\
**Created:** [August 14, 2021, 3:01pm UTC](https://discourse.julialang.org/t/typing-functions-arguments-representing-tuples-of-custom-structs/66395 "2021-08-14T15:01:17Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![claudio20497](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/claudio20497/32/36602_2.png) [@claudio20497](https://discourse.julialang.org/u/claudio20497)\
**Post date:** [August 14, 2021, 3:01pm UTC](https://discourse.julialang.org/t/typing-functions-arguments-representing-tuples-of-custom-structs/66395/1 "2021-08-14T15:01:18Z")

</div>

Hello,

Considering the following struct:

```julia
struct my_struct{A <: Function,B <: Function}
    a::A
    b::B
end

```

I would like to write a function `func` that accepts an `OrderedDict` which values are `Tuple`s of an unknown amount of `my_struct`s. I tried typing its arguments:

```julia
function func(od::OrderedDict{Any,Tuple{Vararg{my_struct{<:Function, <:Function }}}}) 
    # do stuff
    od
end

```

But if I try it:

```julia
using DataStructures
my_struct_1 = my_struct(Base.:+ , Base.:- )
my_struct_2 = my_struct(Base.:* , Base.:/ )

od = OrderedDict("a" => (my_struct_1 ,my_struct_2 ))

func(od)

```

I get:

```julia
ERROR: MethodError: no method matching func(::OrderedDict{String, Tuple{my_struct{typeof(+), typeof(-)}, my_struct{typeof(*), typeof(/)}}})
Closest candidates are:
  func(::OrderedDict{Any, Tuple{Vararg{my_struct{var"#s1", var"#s3"} where {var"#s1"<:Function, var"#s3"<:Function}, N} where N}}) at REPL[3]:1
Stacktrace:
 [1] top-level scope
   @ REPL[7]:1

```

**How may I correctly type `func`’s argument?**

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [August 14, 2021, 3:05pm UTC](https://discourse.julialang.org/t/typing-functions-arguments-representing-tuples-of-custom-structs/66395/2 "2021-08-14T15:05:04Z")

</div>

> [@claudio20497](#):
>
> `OrderedDict{Any`

maybe just don’t type it? Your keys are `Any` anyway.

~~The reason your current code doesn’t work I suspect is because `Vararg` requires all the args same type, `my_struct_1` and `my_struct_2` has different types~~

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [August 14, 2021, 3:17pm UTC](https://discourse.julialang.org/t/typing-functions-arguments-representing-tuples-of-custom-structs/66395/3 "2021-08-14T15:17:29Z")

</div>

also the `Any` needs to be `<:Any`, working example:

```julia
julia> function func(od::T) where T <: Dict{<:Any, <:Tuple{Vararg{my_struct}}}
           # do stuff
           od
       end
func (generic function with 1 method)

julia> my_struct_1 = my_struct(Base.:+ , Base.:- )

julia> func(Dict("a" => (my_struct_1 ,my_struct_1 )))
Dict{String, Tuple{my_struct{typeof(+), typeof(-)}, my_struct{typeof(+), typeof(-)}}} with 1 entry:
  "a" => (my_struct{typeof(+), typeof(-)}(+, -), my_struct{typeof(+), typeof(-)}(+, -))

julia> my_struct_2 = my_struct(Base.:* , Base.:/ )

julia> func(Dict("a" => (my_struct_1 ,my_struct_2 )))
Dict{String, Tuple{my_struct{typeof(+), typeof(-)}, my_struct{typeof(*), typeof(/)}}} with 1 entry:
  "a" => (my_struct{typeof(+), typeof(-)}(+, -), my_struct{typeof(*), typeof(/)}(*, /))

```

---

<div class="post-metadata">

**Author:** ![claudio20497](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/claudio20497/32/36602_2.png) [@claudio20497](https://discourse.julialang.org/u/claudio20497)\
**Post date:** [August 14, 2021, 3:26pm UTC](https://discourse.julialang.org/t/typing-functions-arguments-representing-tuples-of-custom-structs/66395/4 "2021-08-14T15:26:25Z")

</div>

Thanks.

Could you (or someone) please explain (or refer me to an explanation of) why this works while directly tipying the arguments like the initial post doesn’t? I tried to read the [docs](https://docs.julialang.org/en/v1/manual/types/) but I couldn’t find the answer.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [August 14, 2021, 3:32pm UTC](https://discourse.julialang.org/t/typing-functions-arguments-representing-tuples-of-custom-structs/66395/5 "2021-08-14T15:32:55Z")

</div>

```julia
julia> function func(od::Dict{<:Any, <:Tuple{Vararg{my_struct}}})
                  # do stuff
                  od
              end

```

is identical, moving it out was just clearer when I was working on it.

In fact, all you missed was `<:Any, <:Tuple..`, the two `<:` inside the parameter of `Dict`

---

<div class="post-metadata">

**Author:** ![claudio20497](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/claudio20497/32/36602_2.png) [@claudio20497](https://discourse.julialang.org/u/claudio20497)\
**Post date:** [August 15, 2021, 10:18am UTC](https://discourse.julialang.org/t/typing-functions-arguments-representing-tuples-of-custom-structs/66395/6 "2021-08-15T10:18:54Z")

</div>

Thanks.

Sorry for the insistence, but then why does `::Dict{<:Any, <:Tuple{Vararg{my_struct}}}` work and `::Dict{Any,Tuple{Vararg{my_struct}}}` doesn’t? What does the `<:` do besides specifying that there should be a subtype of what is on the right?

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [August 15, 2021, 10:26am UTC](https://discourse.julialang.org/t/typing-functions-arguments-representing-tuples-of-custom-structs/66395/7 "2021-08-15T10:26:48Z")

</div>

```julia
julia> Vector{String} <: Vector{Any}
false

julia> Vector{String} <: Vector{<:Any}
true

```

does this make it clear?

[https://docs.julialang.org/en/v1/manual/types/#man-parametric-composite-types](https://docs.julialang.org/en/v1/manual/types/#man-parametric-composite-types)

people talk about this as “Julia’s type parameters are invariant”

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [August 15, 2021, 10:40am UTC](https://discourse.julialang.org/t/typing-functions-arguments-representing-tuples-of-custom-structs/66395/8 "2021-08-15T10:40:35Z")

</div>

[https://m3g.github.io/JuliaNotes.jl/stable/typevariance/](https://m3g.github.io/JuliaNotes.jl/stable/typevariance/)
