Matching type variables

Whenever a type variable occurs more than once in a method signature, it is used to enforce the same type as determined across all positions where it occurs. Consider the following function:

add(a::Array{T,1}, x::T) where {T <: Real} = (T, a .+ x)

The add function takes an Array{T} and a value of type T. It returns a tuple of T and the result of adding the value to the array. Intuitively, we want the type T to be consistent across both arguments. In other words, we would want the function to be specialized in each of the realizations of T when the function is called. Obviously, the function works great when the type agrees:

In the first case, T is determined to be Int64, and in the second case, T is determined to be Float64. Perhaps not too surprisingly, we may get a method error when the types do not match:

Since we said that T could be an abstract type, could we dispatch to this method, as T could be considered Real? The answer is no, because parametric types are invariant! An array of Real objects is not the same as an array of Int64 values. More formally, Array{Int} is not a subtype of Array{Real}.

It gets a little more interesting when T is an abstract type in the array. Let's try this:

Here, T is unambiguously set to Signed, and because Int8 is a subtype of Signed, the method is dispatched properly.

Next, we will look into another unique typing feature called the diagonal rule.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.161.116