Partial Application in Swift
You might be wondering what partial application is?
Partial application is a concept where you create a new function by pre-filling some of the arguments of an existing function. Swift doesn’t have built-in support for partial application directly, but you can achieve it using closures.
Let’s look at an example to illustrate how you can achieve partial application in Swift.
Example: Partial Application
Suppose you have a function that takes three parameters:
func multiply(a: Int, b: Int, c: Int) -> Int {
return a * b * c
}
You can create a partially applied function by fixing some of the arguments using closures.
Step-by-Step Partial Application
- Create a Function that Partially Applies Arguments:
func partiallyAppliedMultiply(a: Int) -> (Int, Int) -> Int {
return { b, c in
return multiply(a: a, b: b, c: c)
}
}
2. Use the Partially Applied Function:
let multiplyBy2 = partiallyAppliedMultiply(a: 2)
let result = multiplyBy2(3, 4) // This will be 2 * 3 * 4 = 24
print(result) // Output: 24
Explanation
- Original Function:
multiply(a:b:c:)
takes threeInt
arguments and returns their product. - Partial Application Function:
partiallyAppliedMultiply(a:)
is a function that takes one argumenta
and returns a closure. This closure takes the remaining two argumentsb
andc
and calls the originalmultiply
function with all three arguments.
Let’s consider a real-world example in iOS development where partial application can be useful
Scenario: Custom Button Styles in SwiftUI
Suppose you want to create buttons with a common set of styles, but with different background colors and titles.
Step-by-Step Example
- Define a View Modifier for Button Styles:
First, let’s create a custom view modifier that applies common styles to buttons.
import SwiftUI
struct CommonTextStyle: ViewModifier {
let font: Font
let borderColor: Color
func body(content: Content) -> some View {
content
.font(font)
.padding()
.background(Color.white)
.border(borderColor, width: 2)
.cornerRadius(8)
}
}
2. Create a Partially Applied Function for the Modifier:
Next, create a function that partially applies the common styles, returning a function that applies the specific styles. So we want to keep other styles same but have different text and background for each button.
func partiallyApplyTextStyle(font: Font, borderColor: Color) -> (Text, Color) -> AnyView {
return { title, backgroundColor in
AnyView(title
.padding()
.background(backgroundColor)
.modifier(CommonTextStyle(font: font, borderColor: borderColor)))
}
}
3. Use the Partially Applied Function in SwiftUI Views:
Now, you can create specific buttons with different titles and background colors using the partially applied function.
let commonFont = Font.system(size: 16, weight: .medium)
let commonBorderColor = Color.black
let applyTextStyle = partiallyApplyTextStyle(font: commonFont, borderColor: commonBorderColor)
struct ContentView: View {
var body: some View {
VStack {
applyTextStyle(Text("Primary"), .blue)
applyTextStyle(Text("Secondary"), .gray)
}
.padding()
}
}
#Preview {
ContentView()
}
This example demonstrates how partial application can be applied to SwiftUI to create reusable and maintainable view components with common styles.
Explanation
- View Modifier:
CommonTextStyle
is a custom view modifier that applies common styles to the content. - Partial Application Function:
partiallyApplyTextStyle(font:borderColor:)
takes common properties (font and border color) and returns a closure. This closure takes specific properties (title and background color) and returns anAnyView
wrapping the styled content. - Usage: You create specific button styles like
CommonTextStyle
using the partially applied function. These styles automatically include the common font and border color, so you only need to provide the title and background color.
Benefits
- Reusability: You avoid repeating the code to set the common styles for every button.
- Maintainability: If the common styles change, you only need to update them in one place.
- Readability: The code becomes cleaner and more focused on the specific styles for each button.