Thursday, September 24, 2015 [Tweets] [Favorites]

Custom Swift Pattern Matching Operators

Ole Begemann:

We know that greaterThan(0) must produce a function that takes a value and returns Bool. So in turn, greaterThan must be a function that takes another value and returns the first function.

[…]

Swift provides a special syntax for the definition of curried functions that mimics how they are called.

[…]

It’s impossible with this solution to give the compiler any hints for exhaustiveness checking, so it will always force us to provide a default case. If you are certain that your patterns cover every possible value, it is a good idea to put a fatalError() call into the default case to document your expectation that this code path should never get hit.

[…]

Again, note that the missing whitespace between operators and operands is significant.

[…]

As a more practical example, suppose you want to check a string against several prefixes and suffixes.

Update (2015-10-14): Ole Begemann:

Ranges and intervals in Swift serve similar purposes but have different implementations and generic constraints. Ranges are based on indexes and are used most often in the context of collections. The fact that a range can’t contain the maximum value of a type can make them unsuitable for working with intervals of numbers. Intervals work with all Comparable types and don’t have the maximum-value limitation.

While custom operators should be used very sparingly, I’d argue that in this case they significantly improve readability without harming comprehensibility – the prefix and postfix operators are so close in meaning to their binary counterparts that even readers unfamiliar with the code should have no trouble understanding them.

Ole Begemann:

This works, but doing this for every method we want to use in this way quickly becomes tedious. So let’s write a generic function, flip, that moves the first argument of a curried function to the back, right before the final return value.

Comments

Stay up-to-date by subscribing to the Comments RSS Feed for this post.

Leave a Comment