for (first, second) in zip(elements, elements.dropFirst()) {
print(first, second)
}
forEach (or a derivative) is bad here for iteration. It is better to use a for-in. forEach has side-effects (breaking FP) and subtle weirdnesses with Swift (breaking good Swift). for-in is more powerful and cleaner. But the creation of the actual sequence is classic FP: zip with dropFirst.
Note that this is a sequence of tuples, not arrays as you wrote. I don't think you want arrays here, given the syntax you suggest (though you could achieve that with a map if you did).
You can get the syntax you suggest with this, but it's not as flexible as the for-in, and has subtle edge cases (for example if the closure includes a return it behaves like a continue):
extension Sequence {
func forEachTwo(_ f: ((Element, Element) -> Void)) {
for element in zip(self, dropFirst()) {
f(element.0, element.1)
}
}
}