Swift의 함수 커링

Apr 03 2023
소개: 함수 커링은 여러 인수를 받는 함수를 각각 단일 인수를 받는 일련의 함수로 변환하는 함수형 프로그래밍 기술입니다. 미국 수학자 Haskell Curry가 이 기술을 개발하여 커링이라고 합니다.

소개:

함수 커링은 여러 인수를 받는 함수를 각각 단일 인수를 받는 일련의 함수로 변환하는 함수형 프로그래밍 기술입니다.

미국 수학자 Haskell Curry가 이 기술을 개발하여 커링이라고 합니다.

따라서 f(a, b, c, …)와 같은 함수는 f(a)(b)(c)…

이 프로세스는 모든 인수가 제공되고 원래 함수를 평가할 수 있을 때까지 각 인수에 대해 새 함수를 반환합니다. 커리 함수라고도 하는 결과 함수를 결합하고 구성하여 더 복잡한 기능을 만들 수 있습니다.

Currying은 일부 인수가 함수에 전달되고 나머지 인수를 기대하는 새 함수가 반환되는 부분 함수 적용을 가능하게 합니다.

예제 1: 단순 추가 기능

예를 들어 두 개의 인수를 사용하는 다음 함수를 고려하십시오.

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

add(2, 3) // output: 5

  1. 이 함수는 두 개의 인수만 필요합니다.
  2. 두 개 이상의 매개변수를 사용하여 add 함수를 호출할 수 없습니다 .

func curriedAdd(_ x: Int) -> (Int) -> Int {
    return { y in
        return x + y
    }
}

// Now we can call this curried function like this:

print(CurriedAdd(2)(3)) // 5

// we can also call it like this

let addTwo = curriedAdd(2) // (Int) -> Int
print(addTwo(3)) // 5

// Add three numbers using curried function.

curriedAdd(CurriedAdd(5)(2))(3) // 10

예 2: URL 구성

이 예제에서는 ' createURL ' 함수를 사용하여 URL 문자열 목록을 생성합니다 . 이 함수는 baseURL 및 경로를 인수로 사용하고 이러한 매개변수와 함께 호출될 때 새 URL 문자열을 반환합니다.

func createURL(_ baseURL: String, _ path: String) -> String {
    let scheme = "https";
    return "\(scheme)://\(baseURL)/\(path)"
}

// create URLs for our main site
let homeURL = createURL("mysite.com", "");
let loginURL = createURL("mysite.com", "login");
let productsURL = createURL("mysite.com", "products");
let contactURL = createURL("mysite.com", "contact-us");

// create URLs for our careers site
let careersHomeURL = createURL("mysite-careers.com", "");
let careersLoginURL = createURL("mysite-careers.com", "login");

func curriedCreateURL(_ baseURL: String) -> (String) -> String {
    return { path in
        let scheme = "https";
        return "\(scheme)://\(baseURL)/\(path)"
    }
}

// we create a new functions with the baseURL value returns another function.
let createSiteURL = curriedCreateURL("mysite.com");
let createCareersURL = curriedCreateURL("mysite-careers.com");

// create URLs for our main site
let homeURLCurried = createSiteURL("");
let loginURLCurried = createSiteURL("login");
let productsURLCurried = createSiteURL("products");
let contactURLCurried = createSiteURL("contact-us");

// create URLs for our career site
let careersHomeURLCurried = createCareersURL("");
let careersLoginURLCurried = createCareersURL("login");

다음으로 새 URL을 구성하는 데 사용하는 createSiteURL 및 createCareersURL 과 같은 부분 함수 애플리케이션을 만들었습니다 . 함수 커링을 사용하여 함수 호출에서 기본 URL의 반복을 제거했습니다.

예 3: 비용이 많이 드는 프로세스 분리

배송 주소 및 생성 날짜와 함께 여러 국가의 방대한 소포 목록을 포함하는 소포 회사의 대규모 데이터 샘플이 있다고 가정해 보겠습니다.

var globalParcels: Parcels = [
    Parcel(createdDate: 1,
           location: "US",
           shippingAddress: ....
           ),
    Parcel(createdDate: 2,
           location: "AUS",
          shippingAddress: ....
           ),
    Parcel(createdDate: 3,
           location: "US",
           shippingAddress: ....
           )
    // .........
]

func sortParcelsByCountry(_ parcels: Parcels, _ country: String, _ sortOrder: String) -> Parcels {
    let countryParcels = parcels.filter({ $0.location == country })
    if sortOrder == "ascending" {
        return countryParcels.sorted { $0.created > $1.created }
    } else {
        return countryParcels.sorted { $0.created < $1.created }
    }
}

let ausParcelsAsc = sortParcelsByCountry(globalParcels, "AUS", "ascending")
let ausParcelsDsc = sortParcelsByCountry(globalParcels, "AUS", "descending")

func sortParcels(_ parcels: Parcels) -> (String) -> (String) -> Parcels {
    return { country in
        let countryParcels = parcels.filter({ $0.location == country })
        return { sortOrder in
            if sortOrder == "ascending" {
                return countryParcels.sorted { $0.created > $1.created }
            } else {
                return countryParcels.sorted { $0.created < $1.created }
            }
        }
    }
}

let sortAusParcelsBy = sortParcels(globalParcels)("AUS");

let ausParcelsAsc1 = sortAusParcelsBy("ascending");
let ausParcelsDsc1 = sortAusParcelsBy("descending");

결론:

함수 커링은 더 유연하고 재사용 가능한 코드를 허용하기 때문에 함수형 프로그래밍에 유용합니다. 함수를 더 작은 함수의 시퀀스로 분해하여 다양한 방식으로 구성하여 동작이 다른 새 함수를 만들 수 있습니다.

Currying은 코드를 다음과 같이 만듭니다.

  1. 청소기.
  2. 덜 반복적인 매개변수 전달 및 덜 장황한 코드.
  3. 더 구성 가능합니다.
  4. 재사용 가능.