Even putting aside the slim difference between an infinite Collection
and one that is very large, I would say that a key problem with splitting the hierarchy into FiniteCollection
and InfiniteCollection
is that the type system will not be able to help you maintain the separation in many cases. So this will require an escape hatch, like .assumingFinite
or similar, to assert that the Collection
is actually finite and convert between them, or to call methods that you know are reasonable for your particular infinite Collection
and given parameters.
Things like count
, map
, etc. should obviously not be called directly on an infinite Collection
, though map
can be on a lazy view, but other parts of the API are not so clear cut. Quickly skimming the Collection
documentation and Sequence
documentation, it seems like it would be ambiguous as to whether the resulting Collection
is finite or infinite, or whether the method is reasonable to call (e.g. won't infinite loop) as it depends on the contents of the Collection
and the given parameters, in the following cases:
subscript(bounds: Range<Self.Index>)
index(of:)
index(where:)
distance(from:to:)
-
split(separator:maxSplits:omittingEmptySubsequences:)
, which can be safe given judicial use ofmaxSplits
and some knowledge of the contents first(where:)
prefix(while:)
-
lexicographicallyPrecedes(_:)
theoretically safe if you know the two are not equal, I guess
And I'm not immediately sure about things like prefix(upTo:)
, suffix(from:)
, and things like starts(with:)
which are safe if only one of the Sequence
s is infinite, but not if both are. So the situation is kind of messy and it's hard to strike a balance between using the type system to help developers and removing or hiding possibly useful functionality.