Skip to content

Instantly share code, notes, and snippets.

@venkatperi
Created June 4, 2014 15:53
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save venkatperi/209b9fa2946a7151efc0 to your computer and use it in GitHub Desktop.
Save venkatperi/209b9fa2946a7151efc0 to your computer and use it in GitHub Desktop.
Closure Currying in Swift
struct S0<V> {
typealias F = () -> V
}
struct S1<T1,V>{
typealias F = (T1) -> V
}
//0, 0
func curry<T1, V>(f: S1<T1, V>.F, a1:T1) -> S0<V>.F {
return { () -> V in f(a1) }
}
struct S2<T1, T2,V>{
typealias F = (T1, T2) -> V
}
//1, 0
func curry<T1, T2, V>(f: S2<T1, T2, V>.F, a1:T1) -> S1<T2, V>.F {
return { (a2:T2) -> V in f(a1, a2) }
}
//1, 1
func curry<T1, T2, V>(f: S2<T1, T2, V>.F, a1:T1, a2:T2) -> S0<V>.F {
return { () -> V in f(a1, a2) }
}
struct S3<T1, T2, T3,V>{
typealias F = (T1, T2, T3) -> V
}
//2, 0
func curry<T1, T2, T3, V>(f: S3<T1, T2, T3, V>.F, a1:T1) -> S2<T2, T3, V>.F {
return { (a2:T2, a3:T3) -> V in f(a1, a2, a3) }
}
//2, 1
func curry<T1, T2, T3, V>(f: S3<T1, T2, T3, V>.F, a1:T1, a2:T2) -> S1<T3, V>.F {
return { (a3:T3) -> V in f(a1, a2, a3) }
}
//2, 2
func curry<T1, T2, T3, V>(f: S3<T1, T2, T3, V>.F, a1:T1, a2:T2, a3:T3) -> S0<V>.F {
return { () -> V in f(a1, a2, a3) }
}
struct S4<T1, T2, T3, T4,V>{
typealias F = (T1, T2, T3, T4) -> V
}
//3, 0
func curry<T1, T2, T3, T4, V>(f: S4<T1, T2, T3, T4, V>.F, a1:T1) -> S3<T2, T3, T4, V>.F {
return { (a2:T2, a3:T3, a4:T4) -> V in f(a1, a2, a3, a4) }
}
//3, 1
func curry<T1, T2, T3, T4, V>(f: S4<T1, T2, T3, T4, V>.F, a1:T1, a2:T2) -> S2<T3, T4, V>.F {
return { (a3:T3, a4:T4) -> V in f(a1, a2, a3, a4) }
}
//3, 2
func curry<T1, T2, T3, T4, V>(f: S4<T1, T2, T3, T4, V>.F, a1:T1, a2:T2, a3:T3) -> S1<T4, V>.F {
return { (a4:T4) -> V in f(a1, a2, a3, a4) }
}
//3, 3
func curry<T1, T2, T3, T4, V>(f: S4<T1, T2, T3, T4, V>.F, a1:T1, a2:T2, a3:T3, a4:T4) -> S0<V>.F {
return { () -> V in f(a1, a2, a3, a4) }
}
struct S5<T1, T2, T3, T4, T5,V>{
typealias F = (T1, T2, T3, T4, T5) -> V
}
//4, 0
func curry<T1, T2, T3, T4, T5, V>(f: S5<T1, T2, T3, T4, T5, V>.F, a1:T1) -> S4<T2, T3, T4, T5, V>.F {
return { (a2:T2, a3:T3, a4:T4, a5:T5) -> V in f(a1, a2, a3, a4, a5) }
}
//4, 1
func curry<T1, T2, T3, T4, T5, V>(f: S5<T1, T2, T3, T4, T5, V>.F, a1:T1, a2:T2) -> S3<T3, T4, T5, V>.F {
return { (a3:T3, a4:T4, a5:T5) -> V in f(a1, a2, a3, a4, a5) }
}
//4, 2
func curry<T1, T2, T3, T4, T5, V>(f: S5<T1, T2, T3, T4, T5, V>.F, a1:T1, a2:T2, a3:T3) -> S2<T4, T5, V>.F {
return { (a4:T4, a5:T5) -> V in f(a1, a2, a3, a4, a5) }
}
//4, 3
func curry<T1, T2, T3, T4, T5, V>(f: S5<T1, T2, T3, T4, T5, V>.F, a1:T1, a2:T2, a3:T3, a4:T4) -> S1<T5, V>.F {
return { (a5:T5) -> V in f(a1, a2, a3, a4, a5) }
}
//4, 4
func curry<T1, T2, T3, T4, T5, V>(f: S5<T1, T2, T3, T4, T5, V>.F, a1:T1, a2:T2, a3:T3, a4:T4, a5:T5) -> S0<V>.F {
return { () -> V in f(a1, a2, a3, a4, a5) }
}
struct S6<T1, T2, T3, T4, T5, T6,V>{
typealias F = (T1, T2, T3, T4, T5, T6) -> V
}
//5, 0
func curry<T1, T2, T3, T4, T5, T6, V>(f: S6<T1, T2, T3, T4, T5, T6, V>.F, a1:T1) -> S5<T2, T3, T4, T5, T6, V>.F {
return { (a2:T2, a3:T3, a4:T4, a5:T5, a6:T6) -> V in f(a1, a2, a3, a4, a5, a6) }
}
//5, 1
func curry<T1, T2, T3, T4, T5, T6, V>(f: S6<T1, T2, T3, T4, T5, T6, V>.F, a1:T1, a2:T2) -> S4<T3, T4, T5, T6, V>.F {
return { (a3:T3, a4:T4, a5:T5, a6:T6) -> V in f(a1, a2, a3, a4, a5, a6) }
}
//5, 2
func curry<T1, T2, T3, T4, T5, T6, V>(f: S6<T1, T2, T3, T4, T5, T6, V>.F, a1:T1, a2:T2, a3:T3) -> S3<T4, T5, T6, V>.F {
return { (a4:T4, a5:T5, a6:T6) -> V in f(a1, a2, a3, a4, a5, a6) }
}
//5, 3
func curry<T1, T2, T3, T4, T5, T6, V>(f: S6<T1, T2, T3, T4, T5, T6, V>.F, a1:T1, a2:T2, a3:T3, a4:T4) -> S2<T5, T6, V>.F {
return { (a5:T5, a6:T6) -> V in f(a1, a2, a3, a4, a5, a6) }
}
//5, 4
func curry<T1, T2, T3, T4, T5, T6, V>(f: S6<T1, T2, T3, T4, T5, T6, V>.F, a1:T1, a2:T2, a3:T3, a4:T4, a5:T5) -> S1<T6, V>.F {
return { (a6:T6) -> V in f(a1, a2, a3, a4, a5, a6) }
}
//5, 5
func curry<T1, T2, T3, T4, T5, T6, V>(f: S6<T1, T2, T3, T4, T5, T6, V>.F, a1:T1, a2:T2, a3:T3, a4:T4, a5:T5, a6:T6) -> S0<V>.F {
return { () -> V in f(a1, a2, a3, a4, a5, a6) }
}
struct S7<T1, T2, T3, T4, T5, T6, T7,V>{
typealias F = (T1, T2, T3, T4, T5, T6, T7) -> V
}
//6, 0
func curry<T1, T2, T3, T4, T5, T6, T7, V>(f: S7<T1, T2, T3, T4, T5, T6, T7, V>.F, a1:T1) -> S6<T2, T3, T4, T5, T6, T7, V>.F {
return { (a2:T2, a3:T3, a4:T4, a5:T5, a6:T6, a7:T7) -> V in f(a1, a2, a3, a4, a5, a6, a7) }
}
//6, 1
func curry<T1, T2, T3, T4, T5, T6, T7, V>(f: S7<T1, T2, T3, T4, T5, T6, T7, V>.F, a1:T1, a2:T2) -> S5<T3, T4, T5, T6, T7, V>.F {
return { (a3:T3, a4:T4, a5:T5, a6:T6, a7:T7) -> V in f(a1, a2, a3, a4, a5, a6, a7) }
}
//6, 2
func curry<T1, T2, T3, T4, T5, T6, T7, V>(f: S7<T1, T2, T3, T4, T5, T6, T7, V>.F, a1:T1, a2:T2, a3:T3) -> S4<T4, T5, T6, T7, V>.F {
return { (a4:T4, a5:T5, a6:T6, a7:T7) -> V in f(a1, a2, a3, a4, a5, a6, a7) }
}
//6, 3
func curry<T1, T2, T3, T4, T5, T6, T7, V>(f: S7<T1, T2, T3, T4, T5, T6, T7, V>.F, a1:T1, a2:T2, a3:T3, a4:T4) -> S3<T5, T6, T7, V>.F {
return { (a5:T5, a6:T6, a7:T7) -> V in f(a1, a2, a3, a4, a5, a6, a7) }
}
//6, 4
func curry<T1, T2, T3, T4, T5, T6, T7, V>(f: S7<T1, T2, T3, T4, T5, T6, T7, V>.F, a1:T1, a2:T2, a3:T3, a4:T4, a5:T5) -> S2<T6, T7, V>.F {
return { (a6:T6, a7:T7) -> V in f(a1, a2, a3, a4, a5, a6, a7) }
}
//6, 5
func curry<T1, T2, T3, T4, T5, T6, T7, V>(f: S7<T1, T2, T3, T4, T5, T6, T7, V>.F, a1:T1, a2:T2, a3:T3, a4:T4, a5:T5, a6:T6) -> S1<T7, V>.F {
return { (a7:T7) -> V in f(a1, a2, a3, a4, a5, a6, a7) }
}
//6, 6
func curry<T1, T2, T3, T4, T5, T6, T7, V>(f: S7<T1, T2, T3, T4, T5, T6, T7, V>.F, a1:T1, a2:T2, a3:T3, a4:T4, a5:T5, a6:T6, a7:T7) -> S0<V>.F {
return { () -> V in f(a1, a2, a3, a4, a5, a6, a7) }
}
struct S8<T1, T2, T3, T4, T5, T6, T7, T8,V>{
typealias F = (T1, T2, T3, T4, T5, T6, T7, T8) -> V
}
//7, 0
func curry<T1, T2, T3, T4, T5, T6, T7, T8, V>(f: S8<T1, T2, T3, T4, T5, T6, T7, T8, V>.F, a1:T1) -> S7<T2, T3, T4, T5, T6, T7, T8, V>.F {
return { (a2:T2, a3:T3, a4:T4, a5:T5, a6:T6, a7:T7, a8:T8) -> V in f(a1, a2, a3, a4, a5, a6, a7, a8) }
}
//7, 1
func curry<T1, T2, T3, T4, T5, T6, T7, T8, V>(f: S8<T1, T2, T3, T4, T5, T6, T7, T8, V>.F, a1:T1, a2:T2) -> S6<T3, T4, T5, T6, T7, T8, V>.F {
return { (a3:T3, a4:T4, a5:T5, a6:T6, a7:T7, a8:T8) -> V in f(a1, a2, a3, a4, a5, a6, a7, a8) }
}
//7, 2
func curry<T1, T2, T3, T4, T5, T6, T7, T8, V>(f: S8<T1, T2, T3, T4, T5, T6, T7, T8, V>.F, a1:T1, a2:T2, a3:T3) -> S5<T4, T5, T6, T7, T8, V>.F {
return { (a4:T4, a5:T5, a6:T6, a7:T7, a8:T8) -> V in f(a1, a2, a3, a4, a5, a6, a7, a8) }
}
//7, 3
func curry<T1, T2, T3, T4, T5, T6, T7, T8, V>(f: S8<T1, T2, T3, T4, T5, T6, T7, T8, V>.F, a1:T1, a2:T2, a3:T3, a4:T4) -> S4<T5, T6, T7, T8, V>.F {
return { (a5:T5, a6:T6, a7:T7, a8:T8) -> V in f(a1, a2, a3, a4, a5, a6, a7, a8) }
}
//7, 4
func curry<T1, T2, T3, T4, T5, T6, T7, T8, V>(f: S8<T1, T2, T3, T4, T5, T6, T7, T8, V>.F, a1:T1, a2:T2, a3:T3, a4:T4, a5:T5) -> S3<T6, T7, T8, V>.F {
return { (a6:T6, a7:T7, a8:T8) -> V in f(a1, a2, a3, a4, a5, a6, a7, a8) }
}
//7, 5
func curry<T1, T2, T3, T4, T5, T6, T7, T8, V>(f: S8<T1, T2, T3, T4, T5, T6, T7, T8, V>.F, a1:T1, a2:T2, a3:T3, a4:T4, a5:T5, a6:T6) -> S2<T7, T8, V>.F {
return { (a7:T7, a8:T8) -> V in f(a1, a2, a3, a4, a5, a6, a7, a8) }
}
//7, 6
func curry<T1, T2, T3, T4, T5, T6, T7, T8, V>(f: S8<T1, T2, T3, T4, T5, T6, T7, T8, V>.F, a1:T1, a2:T2, a3:T3, a4:T4, a5:T5, a6:T6, a7:T7) -> S1<T8, V>.F {
return { (a8:T8) -> V in f(a1, a2, a3, a4, a5, a6, a7, a8) }
}
//7, 7
func curry<T1, T2, T3, T4, T5, T6, T7, T8, V>(f: S8<T1, T2, T3, T4, T5, T6, T7, T8, V>.F, a1:T1, a2:T2, a3:T3, a4:T4, a5:T5, a6:T6, a7:T7, a8:T8) -> S0<V>.F {
return { () -> V in f(a1, a2, a3, a4, a5, a6, a7, a8) }
}
struct S9<T1, T2, T3, T4, T5, T6, T7, T8, T9,V>{
typealias F = (T1, T2, T3, T4, T5, T6, T7, T8, T9) -> V
}
//8, 0
func curry<T1, T2, T3, T4, T5, T6, T7, T8, T9, V>(f: S9<T1, T2, T3, T4, T5, T6, T7, T8, T9, V>.F, a1:T1) -> S8<T2, T3, T4, T5, T6, T7, T8, T9, V>.F {
return { (a2:T2, a3:T3, a4:T4, a5:T5, a6:T6, a7:T7, a8:T8, a9:T9) -> V in f(a1, a2, a3, a4, a5, a6, a7, a8, a9) }
}
//8, 1
func curry<T1, T2, T3, T4, T5, T6, T7, T8, T9, V>(f: S9<T1, T2, T3, T4, T5, T6, T7, T8, T9, V>.F, a1:T1, a2:T2) -> S7<T3, T4, T5, T6, T7, T8, T9, V>.F {
return { (a3:T3, a4:T4, a5:T5, a6:T6, a7:T7, a8:T8, a9:T9) -> V in f(a1, a2, a3, a4, a5, a6, a7, a8, a9) }
}
//8, 2
func curry<T1, T2, T3, T4, T5, T6, T7, T8, T9, V>(f: S9<T1, T2, T3, T4, T5, T6, T7, T8, T9, V>.F, a1:T1, a2:T2, a3:T3) -> S6<T4, T5, T6, T7, T8, T9, V>.F {
return { (a4:T4, a5:T5, a6:T6, a7:T7, a8:T8, a9:T9) -> V in f(a1, a2, a3, a4, a5, a6, a7, a8, a9) }
}
//8, 3
func curry<T1, T2, T3, T4, T5, T6, T7, T8, T9, V>(f: S9<T1, T2, T3, T4, T5, T6, T7, T8, T9, V>.F, a1:T1, a2:T2, a3:T3, a4:T4) -> S5<T5, T6, T7, T8, T9, V>.F {
return { (a5:T5, a6:T6, a7:T7, a8:T8, a9:T9) -> V in f(a1, a2, a3, a4, a5, a6, a7, a8, a9) }
}
//8, 4
func curry<T1, T2, T3, T4, T5, T6, T7, T8, T9, V>(f: S9<T1, T2, T3, T4, T5, T6, T7, T8, T9, V>.F, a1:T1, a2:T2, a3:T3, a4:T4, a5:T5) -> S4<T6, T7, T8, T9, V>.F {
return { (a6:T6, a7:T7, a8:T8, a9:T9) -> V in f(a1, a2, a3, a4, a5, a6, a7, a8, a9) }
}
//8, 5
func curry<T1, T2, T3, T4, T5, T6, T7, T8, T9, V>(f: S9<T1, T2, T3, T4, T5, T6, T7, T8, T9, V>.F, a1:T1, a2:T2, a3:T3, a4:T4, a5:T5, a6:T6) -> S3<T7, T8, T9, V>.F {
return { (a7:T7, a8:T8, a9:T9) -> V in f(a1, a2, a3, a4, a5, a6, a7, a8, a9) }
}
//8, 6
func curry<T1, T2, T3, T4, T5, T6, T7, T8, T9, V>(f: S9<T1, T2, T3, T4, T5, T6, T7, T8, T9, V>.F, a1:T1, a2:T2, a3:T3, a4:T4, a5:T5, a6:T6, a7:T7) -> S2<T8, T9, V>.F {
return { (a8:T8, a9:T9) -> V in f(a1, a2, a3, a4, a5, a6, a7, a8, a9) }
}
//8, 7
func curry<T1, T2, T3, T4, T5, T6, T7, T8, T9, V>(f: S9<T1, T2, T3, T4, T5, T6, T7, T8, T9, V>.F, a1:T1, a2:T2, a3:T3, a4:T4, a5:T5, a6:T6, a7:T7, a8:T8) -> S1<T9, V>.F {
return { (a9:T9) -> V in f(a1, a2, a3, a4, a5, a6, a7, a8, a9) }
}
//8, 8
func curry<T1, T2, T3, T4, T5, T6, T7, T8, T9, V>(f: S9<T1, T2, T3, T4, T5, T6, T7, T8, T9, V>.F, a1:T1, a2:T2, a3:T3, a4:T4, a5:T5, a6:T6, a7:T7, a8:T8, a9:T9) -> S0<V>.F {
return { () -> V in f(a1, a2, a3, a4, a5, a6, a7, a8, a9) }
}
struct S10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,V>{
typealias F = (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) -> V
}
//9, 0
func curry<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, V>(f: S10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, V>.F, a1:T1) -> S9<T2, T3, T4, T5, T6, T7, T8, T9, T10, V>.F {
return { (a2:T2, a3:T3, a4:T4, a5:T5, a6:T6, a7:T7, a8:T8, a9:T9, a10:T10) -> V in f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) }
}
//9, 1
func curry<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, V>(f: S10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, V>.F, a1:T1, a2:T2) -> S8<T3, T4, T5, T6, T7, T8, T9, T10, V>.F {
return { (a3:T3, a4:T4, a5:T5, a6:T6, a7:T7, a8:T8, a9:T9, a10:T10) -> V in f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) }
}
//9, 2
func curry<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, V>(f: S10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, V>.F, a1:T1, a2:T2, a3:T3) -> S7<T4, T5, T6, T7, T8, T9, T10, V>.F {
return { (a4:T4, a5:T5, a6:T6, a7:T7, a8:T8, a9:T9, a10:T10) -> V in f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) }
}
//9, 3
func curry<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, V>(f: S10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, V>.F, a1:T1, a2:T2, a3:T3, a4:T4) -> S6<T5, T6, T7, T8, T9, T10, V>.F {
return { (a5:T5, a6:T6, a7:T7, a8:T8, a9:T9, a10:T10) -> V in f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) }
}
//9, 4
func curry<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, V>(f: S10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, V>.F, a1:T1, a2:T2, a3:T3, a4:T4, a5:T5) -> S5<T6, T7, T8, T9, T10, V>.F {
return { (a6:T6, a7:T7, a8:T8, a9:T9, a10:T10) -> V in f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) }
}
//9, 5
func curry<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, V>(f: S10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, V>.F, a1:T1, a2:T2, a3:T3, a4:T4, a5:T5, a6:T6) -> S4<T7, T8, T9, T10, V>.F {
return { (a7:T7, a8:T8, a9:T9, a10:T10) -> V in f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) }
}
//9, 6
func curry<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, V>(f: S10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, V>.F, a1:T1, a2:T2, a3:T3, a4:T4, a5:T5, a6:T6, a7:T7) -> S3<T8, T9, T10, V>.F {
return { (a8:T8, a9:T9, a10:T10) -> V in f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) }
}
//9, 7
func curry<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, V>(f: S10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, V>.F, a1:T1, a2:T2, a3:T3, a4:T4, a5:T5, a6:T6, a7:T7, a8:T8) -> S2<T9, T10, V>.F {
return { (a9:T9, a10:T10) -> V in f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) }
}
//9, 8
func curry<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, V>(f: S10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, V>.F, a1:T1, a2:T2, a3:T3, a4:T4, a5:T5, a6:T6, a7:T7, a8:T8, a9:T9) -> S1<T10, V>.F {
return { (a10:T10) -> V in f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) }
}
//9, 9
func curry<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, V>(f: S10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, V>.F, a1:T1, a2:T2, a3:T3, a4:T4, a5:T5, a6:T6, a7:T7, a8:T8, a9:T9, a10:T10) -> S0<V>.F {
return { () -> V in f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment