This does not hold in Julia 1.2.0, but I expect that it should hold:
julia> Vector{Vector{Tuple{T,T}} where Int<:T<:Int} <:
Vector{Vector{Tuple{S1,S1} where S<:S1<:S}} where S
false
Version info:
Julia Version 1.2.0
Commit c6da87ff4b (2019-08-20 00:03 UTC)
Platform Info:
OS: Linux (x86_64-pc-linux-gnu)
CPU: Intel(R) Core(TM) i3-7100U CPU @ 2.40GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-6.0.1 (ORCJIT, skylake)
julia> Vector{Vector{Tuple{T,T}} where Int<:T<:Int} <:
Vector{<:Vector{Tuple{S1,S1} where S<:S1<:S}} where S
true
@rafaqz what version are you in?
Still 1.1.0. But that shouldn't change this kind of subtyping or we are in trouble...
My version has an extra <: in it in the second type, that was my less-than-clear point. You need <: when the type is ultimately parametric. But I'm interested in why that is.
@rafaqz I believe Vector{<:t} is equivalent to Vector{T} where T<:t and not Vector{T<:t}. For example:
julia> Vector{<:Int} == Vector{X} where X<:Int
true
julia> Vector{<:Int} == Vector{Int}
false
Therefore, it is ok that with your Vector{<:...}-type the result is different.
Still, the original example should hold. If we directly use S instead of S1 where S<:S1<:S, which is an equivalent type, subtyping holds as it should:
julia> ta = Vector{Vector{Tuple{T,T}} where Int<:T<:Int}
Array{Array{Tuple{T,T},1} where Int64<:T<:Int64,1}
julia> tb1 = Vector{Vector{Tuple{S1,S1} where S<:S1<:S}} where S
Array{Array{Tuple{S1,S1} where S<:S1<:S,1},1} where S
julia> tb2 = Vector{Vector{Tuple{S,S}}} where S
Array{Array{Tuple{S,S},1},1} where S
julia> tb1 == tb2
true
julia> ta <: tb1
false
julia> ta <: tb2
true
Also, (to elaborate on the title) with a single-element tuple, or otherwise non-diagonal S1, subtyping is correct:
julia> Vector{Vector{Tuple{T}} where Int<:T<:Int} <:
Vector{Vector{Tuple{S1} where S<:S1<:S}} where S
true
julia> Vector{Vector{Tuple{T, Ref{T}}} where Int<:T<:Int} <:
Vector{Vector{Tuple{S1, Ref{S1}} where S<:S1<:S}} where S
true
Most helpful comment
@rafaqz I believe
Vector{<:t}is equivalent toVector{T} where T<:tand notVector{T<:t}. For example:Therefore, it is ok that with your
Vector{<:...}-type the result is different.Still, the original example should hold. If we directly use
Sinstead ofS1whereS<:S1<:S, which is an equivalent type, subtyping holds as it should:Also, (to elaborate on the title) with a single-element tuple, or otherwise non-diagonal
S1, subtyping is correct: