handle(a:) wants an Array, the compiler looks for a way to make
a.dropLast() return an Array.
It happens that
Array.dropLast(_:) has no default argument, and
Collection.dropLast(_:) does not return an Array, so they are not suitable options. On the other hand,
Sequence.dropLast(_:) is a good fit.
You just witnessed method overloading. Another example:
let a = [1, 2, 3]
let b = a.dropLast() // Collection.dropLast
let c = a.dropLast() as ArraySlice<Int> // Collection.dropLast
let d = a.dropLast() as [Int] // Sequence.dropLast
let e: [Int] = a.dropLast() // Sequence.dropLast
I can't find in the Swift Book a documentation of what overloading is, and what are the static resolution rules. In a nutshell, the compiler looks for a suitable implementation in the available overloads, with a preference for the most precise one when there is an ambiguity.
It is this preference which explains why a naked
a.dropLast() is the precise
Collection.dropLast. This preference disfavors the more general
Sequence.dropLast. And it avoids an "Ambiguous use of dropLast()" compiler error.
EDIT: Fixed explanation by replacing
Collection.dropLast(_:) (only the Collection overload has a default argument).