Hi Im trying to use the new variadic generic feature of swift 5.9.
So I have a code that Im trying to refactor it:
func resolve<T>() -> T {
// Resolve method
}
func autoResolve<T>(_ initializer: () -> T) -> T { initializer() }
func autoResolve<T, A>(_ initializer: (A) -> T) -> T { initializer(resolve()) }
func autoResolve<T, A, B>(_ initializer: (A, B) -> T) -> T { initializer(resolve(), resolve()) }
func autoResolve<T, A, B, C>(_ initializer: (A, B, C) -> T) -> T { initializer(resolve(), resolve(), resolve()) }
func autoResolve<T, A, B, C, D>(_ initializer: (A, B, C, D) -> T) -> T { initializer(resolve(), resolve(), resolve(), resolve()) }
func autoResolve<T, A, B, C, D, E>(_ initializer: (A, B, C, D, E) -> T) -> T { initializer(resolve(), resolve(), resolve(), resolve(), resolve()) }
To
func autoResolve<T, each V>(_ initializer: (repeat each V) -> T) -> T { initializer(repeat each resolve()) }
But Im getting this error Pack reference 'each V' can only appear in pack expansion
Where is the problem?
The following code compiles and works. The secret here is that you need to give type evidence. The packed generic type A
must be mentioned somewhere in the repeat
expression. If you don't do that, it's simply not going to work. But if you experiment a bit you'll find it's quite flexible.
protocol Resolver {
func resolve<T>() -> T
}
func auto<T, each A>(_ initializer: @escaping (repeat each A) -> T) -> (any Resolver) -> T {
return { r in
initializer(repeat r.resolve() as (each A))
}
}
struct Foo {
let x: Int
let y: Int
}
let fooResolver = auto(Foo.init)
This is the pattern that I used in my own DI framework to replace the many overloads I have for auto
.