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>
)