Element type of the lazy version is
SubSequence, that would mean requiring a minimum of
I'm totally fine with that - it's there for consistency, but in fact, the other
Sequence.split functions are quite strange and probably worth deprecating. They literally just copy the sequence in to an Array and split that instead, so they all return
Collection versions don't do that, and return an
[SubSequence], as this one does.
If a user really can't lift their generic constraints above
Collection, there are probably important reasons for that (i.e. the sequence truly is single-pass, and they are trying to avoid copies). If they want to copy in to an Array, I think it's safe to assume that they're knowledgeable enough to do that by themselves.
We already have
.joined(), which is available on all sequences and is lazy by default, which supports your argument that this too should be. We could also add a variant for variable-length rows, something like:
func split<S>(lengths: S) -> LazyVariableWidthSplitCollection<Self, S>
where S: Sequence, S.Element == Int
As for more general-purpose reshaping, AFAIK the two main ways to implement it are:
- statically enforce the rank of the collection (i.e. with generic wrappers, whose Element types eventually terminate at some scalar), or
- make the elements a recursive, infinite tower of collections and expect the user to keep track of how many times they subscript (ala TensorFlow's
This, like the existing stdlib split/join functions, concern themselves with the former. But there are certain advantages to the latter (e.g. reshaping the collection at any time). There may be a place for that in the standard library, but it's sufficiently large to deserve its own proposal.