How often have you written code like this:
var object: MyObject?
...
if let unwrapped = object {
doSomething(with: unwrapped)
}
Or, worse, in order to minimize indentation or because you’re relying on a library you don’t control, how often have you written a function like this:
func optionalDoSomething(with myObject: MyObject?) {
if let unwrapped = myObject {
doSomething(with: unwrapped)
}
}
Gross! Well, out of frustration from this happening frequently, I’ve written an operator to alleviate this and allow for more ergonomic functional programming.
infix operator ?>: MultiplicationPrecedence
public func ?><T>(t: T?, f: (T) -> Void) {
if let t = t {
f(t)
}
}
This may look complicated, and feel free to refer back to my article on what a custom operator is. But this will allow us to use optionals and functions that only accept unwrapped values together easily:
var object: MyObject?
object ?> doSomething
which will compile without warnings (whereas trying to call doSomething(with: object)
would result in an error popping up). What’s better is that we can now use this to compose two functions into one by creating a new operator that builds on the one above:
infix operator >?>: Composition
public func >?><A, B>(f: @escaping (A) -> B?, g: @escaping (B) -> Void) -> (A) -> Void {
return { a in
f(a) ?> g
}
}
which we can use like this:
let objectFromString: (String) -> MyObject? = { ... }
let newFunction = objectFromString >?> doSomething
That is, suppose we have a function objectFromString
which returns an optional, but doSomething
requires a non-optional; we could pass an unwrapped version from one to the other by using this >?>
operator. To do this the old way, we’d need to do this:
let objectFromString: (String) -> MyObject? = { ... }
let newFunction: (String) -> Void = { string in
if let myObject = objectFromString(string) {
doSomething(with: myObject)
}
}
Which I find much less readable, not to mention more than double the number of lines.
With operators of these sorts, it becomes very easy to work with optionals in a functional programming codebase.