The diagonal rule says that when a type variable occurs more than once in the covariant position (that is, the method arguments), then the type variable will be restricted to match with concrete types only; however, there is an exception to that rule—when the type variable is unambiguously determined from an invariant position, then it is allowed to be an abstract type rather than a concrete type.
Consider this example:
not_diagonal(A::Array{T,1}, x::T, y::T) where {T <: Number} = T
Unlike the diagonal function from the previous section, this one allows T to be abstract. We can prove it as such:
The reason is that T appears in the first argument in a parametric type. As we know that parametric types are invariant, we have already determined that T is Signed. Because Int64 is a subtype of Signed, everything matched.
In the next section, we will go over the availability of type variables.