Etan Etan - 1 month ago 6
Swift Question

Compactification of Swift Generic Collection where constraint

I have a function that operates on generic collections:

func foo<T: RangeReplaceableCollection>(_ bar: T)
where T.Iterator.Element == UInt8
{
//
}


The function then accesses subranges of that collection, so it needs additional constraints:

func foo<T: RangeReplaceableCollection>(_ bar: T)
where T.Iterator.Element == UInt8,
T.SubSequence: RangeReplaceableCollection,
T.SubSequence.Iterator.Element == T.Iterator.Element
{
//
}


It also calls functions that themselves operate on subranges of the subranges of the collection, so it needs even more constraints:

func foo<T: RangeReplaceableCollection>(_ bar: T)
where T.Iterator.Element == UInt8,
T.SubSequence: RangeReplaceableCollection,
T.SubSequence.Iterator.Element == T.Iterator.Element,
T.SubSequence.SubSequence: RangeReplaceableCollection,
T.SubSequence.SubSequence.Iterator.Element ==
T.SubSequence.Iterator.Element
{
//
}



  • Is there any way how this can be cleaned up?

  • Is there at least a way to hide all those where clauses behind a
    typealias
    ?

  • If not, is there a proposal that addresses this issue?


Answer

A collections subsequence need not have the same type as the collection itself, but – as far as I know – the subsequence of a subsequence has the same type as the subsequence itself for all collections defined in the standard library. Therefore one additional constraint

    T.SubSequence.SubSequence == T.SubSequence

should solve your problem for arbitrarily nested subsequences:

func foo<T: RangeReplaceableCollection>(_ bar: T)
    where T.Iterator.Element == UInt8,
    T.SubSequence: RangeReplaceableCollection,
    T.SubSequence.Iterator.Element == T.Iterator.Element,
    T.SubSequence.SubSequence == T.SubSequence
{
   // ...
}
Comments