콘텐츠로 건너뛰기
Home » 커링함수 코드 만들기

커링함수 코드 만들기

Swift의 차기 버전에서는 자동 커링 함수를 만드는 기능이 제거된다고 한다.  예를 들어

func add(x: Int)(_ y:Int) -> Int { return x + y }
let plusOne = add(1)
let y = plusOne(4)
// y = 5

이런 형태로 함수를 만들 때부터 커링을 지원하도록 하던 기능이 없어진다. 커링함수는 이 기능을 쓰지 않고도 클로저를 리턴하는 함수를 이용해서 만들 수는 있다.

func curry <A, B, C>(body: (A, B) -> C) -> A -> B -> C {
    return { x in
        { y in
            body(x, y)
        }
    }
}
func add(x: Int, y: Int) -> Int { return x + y }
let plusOne = curry(add)(1)
let y = plusOne(4)
// y = 5

이런 커리 함수의 모양은 간단한데, 문제는 인자의 개수만큼 많은 커리 함수를 만들어야 한다는 점이다. 여간 귀찮고 (또 헷갈리는) 작업인 만큼, 이런 커리 함수 코드를 출력해주는 코드를 작성해서 25단 커링 -_- 함수까지 만들어보자.


// curry!
func makeCurryCode(num: Int) -> String? {
guard num > 1 && num < 26 else { return nil }
var typeLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".characters.map{ String($0) }[0…num]
let genericTypeString = typeLetters.joinWithSeparator(", ")
let curriedTypeString = typeLetters.joinWithSeparator(" -> ")
let returnTypeString = typeLetters.removeLast()
let functionArgsTypeString = typeLetters.joinWithSeparator(", ")
let functionArgsString = typeLetters.map{ $0.lowercaseString }.joinWithSeparator(", ")
func makeBody(args:ArraySlice<String>) -> String {
guard !args.isEmpty else {
return "ff(\(functionArgsString))"
}
let (head, tail) = (args.first!, args.dropFirst())
return "{ \(head.lowercaseString) in \(makeBody(tail)) }"
}
return "func curry <\(genericTypeString)> (ff:(\(functionArgsTypeString)) -> \(returnTypeString)) ->"
+ " \(curriedTypeString) { return \(makeBody(typeLetters)) }"
}
Array(1…30).map(makeCurryCode).filter{ $0 != nil }.forEach{ print($0!) }
func curry <A, B, C> (ff:(A, B) -> C) -> A -> B -> C { return { a in { b in ff(a, b) } } }
func curry <A, B, C, D> (ff:(A, B, C) -> D) -> A -> B -> C -> D { return { a in { b in { c in ff(a, b, c) } } } }
func curry <A, B, C, D, E> (ff:(A, B, C, D) -> E) -> A -> B -> C -> D -> E { return { a in { b in { c in { d in ff(a, b, c, d) } } } } }
func curry <A, B, C, D, E, F> (ff:(A, B, C, D, E) -> F) -> A -> B -> C -> D -> E -> F { return { a in { b in { c in { d in { e in ff(a, b, c, d, e) } } } } } }
func curry <A, B, C, D, E, F, G> (ff:(A, B, C, D, E, F) -> G) -> A -> B -> C -> D -> E -> F -> G { return { a in { b in { c in { d in { e in { f in ff(a, b, c, d, e, f) } } } } } } }
func curry <A, B, C, D, E, F, G, H> (ff:(A, B, C, D, E, F, G) -> H) -> A -> B -> C -> D -> E -> F -> G -> H { return { a in { b in { c in { d in { e in { f in { g in ff(a, b, c, d, e, f, g) } } } } } } } }
func curry <A, B, C, D, E, F, G, H, I> (ff:(A, B, C, D, E, F, G, H) -> I) -> A -> B -> C -> D -> E -> F -> G -> H -> I { return { a in { b in { c in { d in { e in { f in { g in { h in ff(a, b, c, d, e, f, g, h) } } } } } } } } }
func curry <A, B, C, D, E, F, G, H, I, J> (ff:(A, B, C, D, E, F, G, H, I) -> J) -> A -> B -> C -> D -> E -> F -> G -> H -> I -> J { return { a in { b in { c in { d in { e in { f in { g in { h in { i in ff(a, b, c, d, e, f, g, h, i) } } } } } } } } } }
func curry <A, B, C, D, E, F, G, H, I, J, K> (ff:(A, B, C, D, E, F, G, H, I, J) -> K) -> A -> B -> C -> D -> E -> F -> G -> H -> I -> J -> K { return { a in { b in { c in { d in { e in { f in { g in { h in { i in { j in ff(a, b, c, d, e, f, g, h, i, j) } } } } } } } } } } }
func curry <A, B, C, D, E, F, G, H, I, J, K, L> (ff:(A, B, C, D, E, F, G, H, I, J, K) -> L) -> A -> B -> C -> D -> E -> F -> G -> H -> I -> J -> K -> L { return { a in { b in { c in { d in { e in { f in { g in { h in { i in { j in { k in ff(a, b, c, d, e, f, g, h, i, j, k) } } } } } } } } } } } }
func curry <A, B, C, D, E, F, G, H, I, J, K, L, M> (ff:(A, B, C, D, E, F, G, H, I, J, K, L) -> M) -> A -> B -> C -> D -> E -> F -> G -> H -> I -> J -> K -> L -> M { return { a in { b in { c in { d in { e in { f in { g in { h in { i in { j in { k in { l in ff(a, b, c, d, e, f, g, h, i, j, k, l) } } } } } } } } } } } } }
func curry <A, B, C, D, E, F, G, H, I, J, K, L, M, N> (ff:(A, B, C, D, E, F, G, H, I, J, K, L, M) -> N) -> A -> B -> C -> D -> E -> F -> G -> H -> I -> J -> K -> L -> M -> N { return { a in { b in { c in { d in { e in { f in { g in { h in { i in { j in { k in { l in { m in ff(a, b, c, d, e, f, g, h, i, j, k, l, m) } } } } } } } } } } } } } }
func curry <A, B, C, D, E, F, G, H, I, J, K, L, M, N, O> (ff:(A, B, C, D, E, F, G, H, I, J, K, L, M, N) -> O) -> A -> B -> C -> D -> E -> F -> G -> H -> I -> J -> K -> L -> M -> N -> O { return { a in { b in { c in { d in { e in { f in { g in { h in { i in { j in { k in { l in { m in { n in ff(a, b, c, d, e, f, g, h, i, j, k, l, m, n) } } } } } } } } } } } } } } }
func curry <A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P> (ff:(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O) -> P) -> A -> B -> C -> D -> E -> F -> G -> H -> I -> J -> K -> L -> M -> N -> O -> P { return { a in { b in { c in { d in { e in { f in { g in { h in { i in { j in { k in { l in { m in { n in { o in ff(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) } } } } } } } } } } } } } } } }
func curry <A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q> (ff:(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P) -> Q) -> A -> B -> C -> D -> E -> F -> G -> H -> I -> J -> K -> L -> M -> N -> O -> P -> Q { return { a in { b in { c in { d in { e in { f in { g in { h in { i in { j in { k in { l in { m in { n in { o in { p in ff(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) } } } } } } } } } } } } } } } } }
func curry <A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R> (ff:(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q) -> R) -> A -> B -> C -> D -> E -> F -> G -> H -> I -> J -> K -> L -> M -> N -> O -> P -> Q -> R { return { a in { b in { c in { d in { e in { f in { g in { h in { i in { j in { k in { l in { m in { n in { o in { p in { q in ff(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) } } } } } } } } } } } } } } } } } }
func curry <A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S> (ff:(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R) -> S) -> A -> B -> C -> D -> E -> F -> G -> H -> I -> J -> K -> L -> M -> N -> O -> P -> Q -> R -> S { return { a in { b in { c in { d in { e in { f in { g in { h in { i in { j in { k in { l in { m in { n in { o in { p in { q in { r in ff(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r) } } } } } } } } } } } } } } } } } } }
func curry <A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T> (ff:(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S) -> T) -> A -> B -> C -> D -> E -> F -> G -> H -> I -> J -> K -> L -> M -> N -> O -> P -> Q -> R -> S -> T { return { a in { b in { c in { d in { e in { f in { g in { h in { i in { j in { k in { l in { m in { n in { o in { p in { q in { r in { s in ff(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s) } } } } } } } } } } } } } } } } } } } }
func curry <A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U> (ff:(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T) -> U) -> A -> B -> C -> D -> E -> F -> G -> H -> I -> J -> K -> L -> M -> N -> O -> P -> Q -> R -> S -> T -> U { return { a in { b in { c in { d in { e in { f in { g in { h in { i in { j in { k in { l in { m in { n in { o in { p in { q in { r in { s in { t in ff(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t) } } } } } } } } } } } } } } } } } } } } }
func curry <A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V> (ff:(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U) -> V) -> A -> B -> C -> D -> E -> F -> G -> H -> I -> J -> K -> L -> M -> N -> O -> P -> Q -> R -> S -> T -> U -> V { return { a in { b in { c in { d in { e in { f in { g in { h in { i in { j in { k in { l in { m in { n in { o in { p in { q in { r in { s in { t in { u in ff(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u) } } } } } } } } } } } } } } } } } } } } } }
func curry <A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W> (ff:(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V) -> W) -> A -> B -> C -> D -> E -> F -> G -> H -> I -> J -> K -> L -> M -> N -> O -> P -> Q -> R -> S -> T -> U -> V -> W { return { a in { b in { c in { d in { e in { f in { g in { h in { i in { j in { k in { l in { m in { n in { o in { p in { q in { r in { s in { t in { u in { v in ff(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v) } } } } } } } } } } } } } } } } } } } } } } }
func curry <A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X> (ff:(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W) -> X) -> A -> B -> C -> D -> E -> F -> G -> H -> I -> J -> K -> L -> M -> N -> O -> P -> Q -> R -> S -> T -> U -> V -> W -> X { return { a in { b in { c in { d in { e in { f in { g in { h in { i in { j in { k in { l in { m in { n in { o in { p in { q in { r in { s in { t in { u in { v in { w in ff(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w) } } } } } } } } } } } } } } } } } } } } } } } }
func curry <A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y> (ff:(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X) -> Y) -> A -> B -> C -> D -> E -> F -> G -> H -> I -> J -> K -> L -> M -> N -> O -> P -> Q -> R -> S -> T -> U -> V -> W -> X -> Y { return { a in { b in { c in { d in { e in { f in { g in { h in { i in { j in { k in { l in { m in { n in { o in { p in { q in { r in { s in { t in { u in { v in { w in { x in ff(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x) } } } } } } } } } } } } } } } } } } } } } } } } }
func curry <A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z> (ff:(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y) -> Z) -> A -> B -> C -> D -> E -> F -> G -> H -> I -> J -> K -> L -> M -> N -> O -> P -> Q -> R -> S -> T -> U -> V -> W -> X -> Y -> Z { return { a in { b in { c in { d in { e in { f in { g in { h in { i in { j in { k in { l in { m in { n in { o in { p in { q in { r in { s in { t in { u in { v in { w in { x in { y in ff(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y) } } } } } } } } } } } } } } } } } } } } } } } } } }