Mastering Infix Operators in Swift: Compose Functions
Learn how the order of parameters and return values affect function composition in Swift and how to improve composability using higher-order functions.
Let’s continue composing functions to create something bigger. Today, I want to discuss how the order of parameters and return values (function signature) impacts function composition in Swift.
Understanding Function Signatures
Consider this example:
1
let uppercased = String.uppercased(with:)
The function signature of uppercased is:
1
(String) -> (Locale?) -> String
This means uppercased takes a String as a parameter and returns another function that takes an optional Locale and returns a String.
For example:
1
let stringToBeUppercasedWithLocale = uppercased("mehmet")
The function signature of stringToBeUppercasedWithLocale is:
1
(Locale?) -> String
We can then use this function as follows:
1
let currentLocalUppercased = stringToBeUppercasedWithLocale(.current)
Why Is This Order Suboptimal?
The issue here is that we first pass the string, and then later provide the locale. However, for better function composition, we would prefer a signature where we first specify the locale and then pass the string. Ideally, the signature should be:
1
(Locale?) -> (String) -> String
This would allow us to reuse the function for multiple strings while keeping the locale fixed.
Transforming the Function Signature
To achieve this transformation, we can use a higher-order function that flips the parameter order.
Here’s a flip function to achieve this:
1
2
3
4
5
6
7
func flip<A, B, C>(_ f: @escaping (A) -> (B) -> C) -> (B) -> (A) -> C {
{ b in
{ a in
f(a)(b)
}
}
}
Applying the flip Function
Using flip, we transform uppercased into a more composable version:
1
let flipUppercased = flip(uppercased)
Now, flipUppercased has the signature:
1
(Locale?) -> (String) -> String
We can now create a localized uppercase function:
1
let flipCurrentLocalUppercased = flipUppercased(.current)
Now, we can reuse flipCurrentLocalUppercased for multiple strings:
1
2
let flipStringThatIsUpperCasedMehmet = flipCurrentLocalUppercased("Mehmet")
let flipStringThatIsUpperCasedBaykar = flipCurrentLocalUppercased("Baykar")
Why This Approach Is Better
- The function becomes more reusable by fixing the locale first.
- It improves readability and reduces redundant code.
- It allows better function composition in functional programming paradigms.
By flipping the parameter order, we achieve a more flexible and composable function, making Swift’s functional capabilities even more powerful.
I’ll continue sharing more insights into functional programming in Swift, so stay tuned!
☕ Support My Work
If you found this post helpful and want to support more content like this, you can buy me a coffee!
Your support helps me continue creating useful articles and tips for fellow developers. Thank you! 🙏