I thought about variadic generics recently because it was anounced that Swift 6 will have this function at here.
I found this thread and read draft of proposal.
Then I want to improve expression of curry
.
One existing idea is this.
func curry<A, B, C, variadic D, Result>(_ fn: @escaping (A, B, C, D...) -> Result) -> ???
It seems to infer type of ???
.
But it is not appropriate for Swift which always describes signature of function.
Another is this.
enum CurryHelper<variadic T, Result> {
#ifempty T
typealias Fn = Result
#else
typealias Fn = (#head(T)) -> CurryHelper<#tail(T), Result: Result>.Fn
#endif
}
I think its good for point of that it is succeeded to express.
But rule of evaluating #ifempty
happens when application of generic parameters is not consistent with existing evaluation of #if
.
#if
is evaluated statically only once if it is used in declaration like enum
.
This is confusing behavior for programmer.
So I propose #condtype
as a new operation to represent branching in compile time.
It can be expressed as below with this.
enum CurryHelper<vairadic T, Result> {
typealias Fn = #condtype(#ifempty(T),
Result,
(#head(T)) -> CurryHelper<#tail(T), Result>.Fn)
}
Or we can eliminate namespace by CurryHelper
.
typealias CurryFn<variadic T, Result> = #condtype(
#ifempty(T),
Result,
(#head(T)) -> CurryFn<#tail(T), Result>
)