Uncategorized

Swift Custom Operator Spotlight: Optional Casting

I don’t know about you, but I often find myself casting objects in Swift. This used to involve writing code like this:

if let myDataSource = tableView.dataSource as? MyDataSource {
  doSomething(to: myDataSource)
}

This is especially annoying when I’m using a functional programming style, as that entails writing a lot of functions, and casting parameters is a pain and makes for ugly code.

So, I wrote a function to do this for me:

public func optionalCast<T, U>(_ t: T) -> U? {
  return t as? U
}

You can use it like this:

doSomething(to: optionalCast(tableView.dataSource))

presuming that doSomething(to:) accepts optionals (if not, see my post about an operator to handle that case). And, better, I turned this into an operator on a function:

prefix operator ~>
public prefix func ~><T, U>(f: @escaping (U) -> Void) -> (T) -> Void {
  return { t in
    if let cast: U = optionalCast(t) {
      f(cast)
    }
  }
}

Now I can use this to easily create functions that accept an arbitrary parameter type, and pass things directly to it:

let doSomethingToDataSource: (UITableViewDataSource) -> Void = ~>doSomething(to:)
doSomethingToDataSource(tableView.dataSource)

Or, if you use functional programming operators from Prelude, you can make it even simpler:

tableView.dataSource |> ~>doSomething(to:)

This is especially useful when composing functions. Suppose a function returns an object which you only care about dealing with if it’s a specific subclass; then, using the Prelude library, you could do something like this:

let newFunction = self.createDataSource >>> ~>doSomething(to:)

which you can then easily add to your pipeline of functions for setting up your datasource.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s