Swift

Currying

zinozino 2022. 11. 30. 23:54

함수  Currying을 알아보도록 하겠습니다.  예시도 어렵고 저도 이해하는데 꽤나 많이 걸려서 차근차근 정리해보도록 하겠습니다.

 

 

"수학과 컴퓨터 과학에서 커링이란 다중 인수를
갖는 함수를 단일 인수를 갖는 함수들의 함수열로 바꾸는 것을 말한다."

 

간단히 말해서 함수에 인수들이 여러 개 일 때  한 개의 인수를 가지는 함수들로 바꾸는 것!

 

 

함수에 인수가 두 개이고 반환되는 값은 1개입니다.

func add(x: Int, y: Int) -> Int {
   x + y
}
// (Int, Int) -> Int

add(x:3, y: 2) // print 5

 

한 개의 인수를 가지는 함수들로 나열하는다는 것은  

아래처럼 바뀌어야겠습니다.

(Int) -> (Int) -> Int

 

함수의 시그니처

func add(x: Int) -> (Int) -> Int

 

x에 인수로 받은 Int값을 y로 명명하고  두 수를 더하는 코드입니다.  인수 두 개를 더하는 함수와  결괏값이 같은 것을 알 수 있습니다.

func add(x: Int) -> (Int) -> Int {
    { y in  x + y }
}

add(x:3)(2) //print 5

 

이러한 방법을 제네릭하게 만들어 함수를 리턴하는 함수를 만들까 합니다.

완성된 함수가 복잡하기 때문에 단계적으로 함수를 완성시켜보도록 하겠습니다.

 

 

A, B를 받아 C를 반환하는 function을 받겠습니다. 

시그니처를 보니   (A) -> (B) -> C로 바꿔줘야 한다는 것을 알 수 있습니다.

func currying<A,B,C>(funtion:  @escaping (A,B) -> C)

 

  반환 값으로 추가해줍니다.

 

currying이라는 함수는 인수를 두 개를 받고 또 다른 하나를 반환하는 함수를 인수로 가지고 있는 함수이고

이 함수는 

(A) 받는 함수를 가지고 (B) 함수를 받아  C를 반환해야 합니다. 

 

함수를 받아서 함수를 반환하죠.

func currying<A,B,C>(fuction: (A,B) -> C) -> (A) -> (B) -> C

 

func currying<A, B, C>(_ f: (A, B) -> C) -> (A) -> (B) -> C {
 // return { a in  } // (A)
 // return { a in { b in // (B)  } // a를 받고, (A)안에서 (B)를 호출하여 b받기 
 // return { a in { b in funtion(a,b) } } // 받은 a,b를 fuction에 넣습니다. 그럼 funtion에서 처리될 겁니다.
}

 

 

⚠️ Escaping closure captures non-escaping parameter 'function'이라는 에러가 발생하게 됩니다. ⚠️

함수 안에서 a, b처리 후에 다시&nbsp; 반환해야 하는 값을&nbsp; 반환해야 하므로 @escaping 키워드를 붙여줘야 합니다.

 

func currying<A, B, C>(_ function: @escaing (A, B) -> C) -> (A) -> (B) -> C {
    { a in { b in function(a,b) } } 
}

 

 

결과!

let curryingFunction = currying(function: add(x:y:))
print(curryingFunction(2)(3))
 //print 5

참고

https://www.pointfree.co/episodes/ep5-higher-order-functions