IndexStyle for pairs iterator?

I was a bit surprised to see that the pairs iterator for Matrix returns CartesianIndices by default. The docstring of pairs includes a section on specifying index style, showing these three signatures:

pairs(IndexLinear(), A)
pairs(IndexCartesian(), A)
pairs(IndexStyle(A), A)

I would have expected the default behaviour of pairs to be

pairs(A) = pairs(IndexStyle(A), A)

but in fact it is

pairs(A::AbstractVector) = pairs(IndexLinear(), A)
pairs(A::AbstractArray)  = pairs(IndexCartesian(), A)

Note that IndexStyle(Array) is always IndexLinear(), for all dimensionalities.

The eachindex function is defined as I expected:

eachindex(A::AbstractArray) = (@inline(); eachindex(IndexStyle(A), A))

and I was treating pairs as simply a convenient version of eachindex that also spat out values, with surprising results.

So two questions:

  1. Why isn’t the defult behaviour of pairs for an array consistent with the array’s IndexStyle? Or why isn’t IndexStyle(Matrix) equal to IndexCartesian()?
  2. What is a convenient way to query the type of the indices of A? For now I have typeof(first(first(pairs(A)))), which seems a bit awkward. What if I only have the type of A, and not A itself?

If I want to do the ‘safe and correct’ version of enumerate(A) (which many misuse, actually), I have to write pairs(IndexLinear(), A), which a bit awkward.

1 Like