# What's the difference between these two types with implicit and explicit parameters?

``````julia> T1 = Vector{S} where {T<:Integer, S<:AbstractUnitRange{T}}
Vector{S} where {T<:Integer, S<:AbstractUnitRange{T}} (alias for Array{S, 1} where {T<:Integer, S<:AbstractUnitRange{T}})

julia> T2 = Vector{S} where {S<:AbstractUnitRange{<:Integer}}
Vector{S} where S<:(AbstractUnitRange{var"#s34"} where var"#s34"<:Integer) (alias for Array{S, 1} where S<:(AbstractUnitRange{var"#s34"} where var"#s34"<:Integer))

julia> T1 == T2
false
``````

Could someone give me an example to explain the difference between the two?

Ah the difference appears to be

``````julia> Vector{AbstractUnitRange{<:Integer}} <: T2
true

julia> Vector{AbstractUnitRange{<:Integer}} <: T1
false
``````
1 Like

Is that intended? Because, I would suppose `<:` is like `<=` and you could chain any number of `xn <= ... <= x2 <= x1` and all variables would share the same upper bound, here it seems like the upper bound is lost (more akin `<`).

The difference is that `T1` requires all `AbstractUnitRange` to have the same eltype `T`, while the second allows different eltypes. Therefore the following are the same:

``````julia> T2 = Vector{S} where {S<:AbstractUnitRange{<:Integer}}
Vector{S} where S<:(AbstractUnitRange{var"#s1"} where var"#s1"<:Integer) (alias for Array{S, 1} where S<:(AbstractUnitRange{var"#s1"} where var"#s1"<:Integer))

julia> T3 = Vector{S} where {T<:Integer, S<:AbstractUnitRange{<:T}}
Vector{S} where {T<:Integer, S<:(AbstractUnitRange{var"#s1"} where var"#s1"<:T)} (alias for Array{S, 1} where {T<:Integer, S<:(AbstractUnitRange{var"#s1"} where var"#s1"<:T)})

julia> T2 == T3
true
``````

(note the difference - in `T3` and additional `<:` is used before `T`.

3 Likes