Introduction
Commonly, If we need unwrapping multiple properties, we can use if let or guard let.
But, Sometimes, many if let, guard patterns make poor readability.
Or If you avoid poor readability, you can define function parameters to optional.
But, You have to unwrap parameters in function.
So, I will introduce new function to unwrap multiple optionals more effectively.
Motivation
I use that functions to unwrapping multiple optionals
func unwrap<A, B>(a: A?, b: B?) -> (A, B)? {
return a.flatMap { a -> (A, B)? in
b.flatMap { b -> (A, B)? in
(a, b)
}
}
}
// swiftlint:disable large_tuple
func unwrap<A, B, C>(a: A?, b: B?, c: C?) -> (A, B, C)? {
return a.flatMap { a -> (A, B, C)? in
b.flatMap { b -> (A, B, C)? in
c.flatMap { c -> (A, B, C)? in
(a, b, c)
}
}
}
}
// swiftlint:disable large_tuple
func unwrap<A, B, C, D>(a: A?, b: B?, c: C?, d: D?) -> (A, B, C, D)? {
return a.flatMap { a -> (A, B, C, D)? in
b.flatMap { b -> (A, B, C, D)? in
c.flatMap { c -> (A, B, C, D)? in
d.flatMap { d -> (A, B, C, D)? in
(a, b, c, d)
}
}
}
}
}
That is usage
func fullName(firstName: String, lastName: String) -> String {
return "\(firstName) \(lastName)"
}
var firstName: String? = "Raynor"
var lastName: String? = "Jim"
let name = unwrap(a: firstName, b: lastName).map(fullName)
If I don't use that function, I have to guard or if let patterns, or make parameters to optional
// That pattern can be a boilerplate code.
if let firstName = self.firstName, let lastName = self.lastName {
let fullName = fullName(firstName: firstName, lastName: lastName)
}
or
// That function is not definitely. because fullName function don't need optional firstName, lastName. and that function don't need return optional String.
func fullName(firstName: String?, lastName: String?) -> String? {
guard let firstName = firstName, let lastName = lastName else {
return nil
}
return "\(firstName) \(lastName)"
}
So I think if swift support multiple optional unwrapping function, we can make a function more definitely.
And I think add unwrap function to Tuple is best way to supporting multiple optional unwrapping.
Proposed solution
// If tuple has unwrap method, result of (firstName, lastName).unwrap() is (String, String)? so you can use map or flatMap to transform that tuple. Then, you don't have to make a boilerplate codes, you can make function more definitely.
let result = (firstName, lastName).unwrap().map(fullName) // (firstName, lastName) is (String?, String?)
I think add unwrap function to Tuple if tuple has optional properties.
But If add unwrap function to tuple that don't have optional properties, It does not seem to be a problem.