Open JD-man opened 2 years ago
func curry<A, B, C>(
_ originalMethod: @escaping (A, B) -> C
) -> (A) -> (B) -> C {
return { a in
{ b in
originalMethod(a, b)
}
}
}
someOperation(1, "number one")
curry(someOperation)(1)("number one")
func flip<A, B, C>(
_ originalMethod: @escaping (A) -> (B) -> C
) -> (B) -> (A) -> C {
return { b in { a in originalMethod(a)(b) } }
}
let curried = curry(someOperation)
let flipped = flip(curried)
aHigherOrderFunction(flipped("a constant"))
extension Int {
func word() -> String? {
let formatter = NumberFormatter()
formatter.numberStyle = .spellOut
return formatter.string(from: self as NSNumber)
}
}
[1, 2, 3, 4, 5].map { $0.word() }
// [Optional("one"), Optional("two"), Optional("three"), Optional("four"), Optional("five")]
Int.word
// (Int) -> () -> Optional<String>
Int.word(1)() // one
Int.word(10)() // ten
Int.word(36)() // thirty-six
func flip<A, C>(
_ originalMethod: @escaping (A) -> () -> C
) -> () -> (A) -> C {
return { { a in originalMethod(a)() } }
}
var flippedWord = flip(Int.word)()
[1, 2, 3, 4, 5].map(flippedWord)
// ["one", "two", "three", "four", "five"]
func reduce<A, C>(
_ originalMethod: @escaping (A) -> () -> C
) -> (A) -> C {
return { a in originalMethod(a)() }
}
var reducedWord = reduce(Int.word)
func mergeFunctions<A, B, C>(
_ f: @escaping (A) -> () -> B,
_ g: @escaping (B) -> () -> C
) -> (A) -> C {
return { a in
let fValue = f(a)()
return g(fValue)()
}
}
func +<A, B, C>(
left: @escaping (A) -> () -> B,
right: @escaping (B) -> () -> C
) -> (A) -> C {
return { a in
let leftValue = left(a)()
return right(leftValue)()
}
}
extension Int {
func word() -> String? {
let formatter = NumberFormatter()
formatter.numberStyle = .spellOut
return formatter.string(from: self as NSNumber)
}
func squared() -> Int {
return self * self
}
}
var mergedFunctions = mergeFunctions(Int.squared, Int.word)
mergedFunctions(2) // four
var addedFunctions = Int.squared + Int.word
addedFunctions(2) // four
(Int.squared + Int.word)(2) // four
정의
예시
Currying 이전
Currying 이후
aHigherOrderFunction { someOperation($0, "a constant") }
에서 클로저 안쪽을 위와 같이 나눠서 사용할 수 있다.Flipping