i keep finding myself trying to extend a Sequence of some generic type, where i want to parameterize the extension over the generic parameter of the Sequence.Element. this is not possible in swift, so i end up writing a bunch of boilerplate like:
extension Sequence<Branch.Epoch<Module>>
{
func find(_ module:Module.ID) -> Tree.Position<Module>?
{
}
}
extension Sequence<Branch.Epoch<Symbol>>
{
func find(_ symbol:Symbol.ID) -> Tree.Position<Symbol>?
{
}
}
extension Sequence<Branch.Epoch<Article>>
{
func find(_ article:Article.ID) -> Tree.Position<Article>?
{
}
}
when what i really want to do is something like:
extension Sequence<some Branch.Epoch<Axis>>
{
func find(_ axis:Axis.ID) -> Tree.Position<Axis>?
{
}
}
or
extension <Axis> Sequence<Branch.Epoch<Axis>>
{
func find(_ axis:Axis.ID) -> Tree.Position<Axis>?
{
}
}
as a workaround it is possible to define a _AnyBranchEpoch protocol with an associated type that can become the Axis parameter, and extend that. but i really struggle to come up with a name for this protocol because _AnyBranchEpoch is just wrong: it is not an existential and this is abusing the word “any”.
_SomeBranchEpoch is a little bit better, but it leads to some _SomeBranchEpoch which also sounds wrong.
how do you handle this?
Karl
(👑🦆)
2
Drop the generic constraints down to the 'find' function, instead of writing it on the extension.
protocol AxisProtocol {
associatedtype ID
}
enum Branch {
struct Epoch<T> {}
}
enum Tree {
struct Position<T> {}
}
extension Sequence {
func find<Axis>(
_ id: Axis.ID
) -> Tree.Position<Axis> where Element == Branch.Epoch<Axis>, Axis: AxisProtocol {
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
fatalError("Not implemented")
}
}
13 Likes
wow, that’s a handy technique! i completely forgot extension members can introduce their own parameterized constraints. thanks!
4 Likes