Funzione Currying in Swift
Introduzione:
Il currying di funzioni è una tecnica nella programmazione funzionale che trasforma una funzione che accetta più argomenti in una serie di funzioni, ognuna delle quali accetta un singolo argomento.
Un matematico americano di nome Haskell Curry ha sviluppato questa tecnica, ecco perché si chiama currying.
Pertanto, una funzione come f(a, b, c, …) può essere convertita in f(a)(b)(c)….
Questo processo restituisce una nuova funzione per ogni argomento finché non sono stati forniti tutti gli argomenti e la funzione originale può essere valutata. Le funzioni risultanti, chiamate anche funzioni al curry , possono essere combinate e composte per creare funzionalità più complesse.
Il currying abilita l'applicazione della funzione parziale , in cui alcuni argomenti vengono passati a una funzione e viene restituita una nuova funzione, in attesa degli argomenti rimanenti.
Esempio 1: funzione Aggiungi semplice
Ad esempio, considera la seguente funzione che accetta due argomenti:
func add(_ x: Int, _ y: Int) -> Int {
return x + y
}
add(2, 3) // output: 5
- Questa funzione prevede solo due argomenti.
- Non possiamo chiamare la funzione add con più di due parametri.
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
Esempio 2: costruzione di URL
In questo esempio, creeremo un elenco di stringhe URL utilizzando la funzione ' createURL ', che accetta baseURL e path come argomenti e restituisce una nuova stringa URL quando viene chiamata con questi parametri.
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");
Successivamente, abbiamo creato applicazioni con funzioni parziali come createSiteURL e createCareersURL , che usiamo per costruire nuovi URL. Utilizzando la funzione currying, abbiamo eliminato la ripetizione dell'URL di base nelle chiamate di funzione.
Esempio 3: isolare il processo costoso
Supponiamo di avere un ampio campione di dati da un'azienda di pacchi, contenente un enorme elenco di pacchi provenienti da diversi paesi insieme ai loro indirizzi di spedizione e alla data in cui sono stati creati.
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");
Conclusione:
Il currying delle funzioni è utile nella programmazione funzionale perché consente un codice più flessibile e riutilizzabile. Scomponendo una funzione in una sequenza di funzioni più piccole, possiamo comporle in vari modi per creare nuove funzioni con comportamenti diversi.
Currying renderà il nostro codice:
- Più pulito.
- Passaggio di parametri meno ripetitivo e codice meno prolisso.
- Più componibile.
- Più riutilizzabile.

![Che cos'è un elenco collegato, comunque? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































