---
title: Functional Swift for Dealing with Optional Values
teaser: Using functional concepts in Swift can bring clarity and safety to everyday
  patterns.
tags: functional programming,swift,haskell,ios
author: Gordon Fontenot
published_on: 2014-10-15
---

Dealing with [Optional values][apple-optionals] (specifically [Implicitly
Unwrapped Optionals][apple-iuo]) is unfortunately an everyday part of our life
as forward-looking iOS developers.  The entirety of the Cocoa API won't be
audited for optionals for a good long while, so these things are here to stay.
This means we're going to introduce some actual runtime errors into our
application where we might not have encountered them before.

[apple-optionals]: https://developer.apple.com/librarY/prerelease/mac/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-XID_485
[apple-iuo]: https://developer.apple.com/librarY/prerelease/mac/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-XID_493

Let's look at a fairly standard Objective-C object that we might be pulling
into our app through a library:

```obj-c
@interface TBUser

@property (nonatomic, copy) NSString *fullName;
@property (nonatomic, copy) NSString *emailAddress;
@property (nonatomic, copy) NSString *twitterUsername;
@property (nonatomic) NSURL *websiteURL;

@end
```

Now, back in our Swift application, we start building a View Model to present
this data to the view object:

```swift
struct UserViewModel {
    let user: TBUser
}
```

This view model is instantiated with an instance of `TBUser` (remember that
using a `Struct` gives us the initializer for free). We can then start
building out the computed properties for the view model to pass the data from
the model:

```swift
extension UserViewModel {
    var displayName: String {
        return user.fullName
    }

    var email: String {
        return user.emailAddress
    }

    var twitterHandle: String {
        return "@\(user.twitterUsername)"
    }
}
```

All of this looks fairly straightforward. However, once we run the application
and view a user, we get a crash:

```log
fatal error: unexpectedly found nil while unwrapping an Optional value
```

Upon bridging to Swift from Objective-C, those properties are being turned
into implicitly unwrapped optionals. And apparently, our library isn't
guaranteeing that we actually get values back for some of these properties.

"This seems simple enough" we say, and throw a quick guard around the
implementation:

```swift
var twitterHandle: String {
    if let username = user.twitterUsername {
        return "@\(username)"
    }

    return ""
}
```

And there we go. Now, when we navigate to that same user, we don't see that
crash. We get the formatted username when there is one, and an empty string
when it doesn't exist.

Except&hellip; that `if let` is kind of gross. And then we start looking around
and realize that this might be something we have to do a lot. It's a fairly
common pattern when dealing with optional values:

1. Check to see if there is a value
1. Do something with the unwrapped value
1. Do something else if the optional is `.None`

Luckily, we can use a functional concept to simplify this for us.

## Enter, fmap

(Quick note for Functional Programming nerds: we're really just talking about
`fmap` in the context of `Optional` here. I know this is a simplification.
Please don't [email me](mailto:gordon@thoughtbot.com).)

The function `fmap` (represented as an infix operator as `<$>` in Haskell and
which we'll define as `<^>` in Swift) can be implemented as so:

```swift
infix operator <^> { associativity left }

func <^><A, B>(f: A -> B, a: A?) -> B? {
    switch a {
    case .Some(let x): return f(x)
    case .None: return .None
    }
}
```

Put into words, `fmap` takes a function and an optional value. If the optional
value is `.Some`, it passes the contained value into the function. If the
optional value is `.None` it just returns `.None`.

So our first step here is to create that function that we want to pass to
`fmap`.

```swift
func usernameFormat(name: String) -> String {
    return "@\(name)"
}
```

Note that now we're dealing with a non-optional instance of `String`. So we
have a guarantee from the compiler that when this function is called, we will
have a name to format. Rad.

Now we can try to start to work that into the original implementation:

```swift
var twitterHandle: String {
    if let username = user.twitterUsername {
        return usernameFormat(username)
    }

    return ""
}
```

Now, we introduce `fmap`. [Hold onto your butts](http://butt.holdings):

```swift
var twitterHandle: String {
    let handle = usernameFormat <^> user.twitterUsername
    return handle ?? ""
}
```

That actually looks really nice to my eye. And we get to take advantage of the
insanely awesome [nil coalescing][apple-nil] operator (`??`). This operator
returns the value of the optional, or the default value if the optional is
`.None`. This is the same as the `fromMaybe` function from Haskell.

[apple-nil]: https://developer.apple.com/library/ios/documentation/swift/conceptual/Swift_Programming_Language/BasicOperators.html#//apple_ref/doc/uid/TP40014097-CH6-XID_124

So again, as a recap, putting into words what's happening here:

We create the `handle` constant (which is of the type `String?` after type
inference) with the return value from `fmap`ing `usernameFormat` over the
optional username. If the username is `.None` this will mean that `handle` is
`.None`. However, if the username is `.Some`, the contained value will be
passed into `usernameFormat`, which will set `handle` to the formatted string,
wrapped in `.Some`.

Then, we return the contained value of `handle`, or an empty string if
`handle` is `.None`.

Whew.

Let's look at a more interesting example.

## Multiple optional values

Now we want to display that website on the screen. We add the following
function to our View Model:

```swift
var website: String {
    let url = user.websiteURL
    return "\(url.host)\(url.path)"
}
```

Navigating to a user in the UI reveals another unexpected bug. Instead of
nicely formatted URLs like `example.com/path`, we have something else
entirely:

    Optional("example.com")/Optional("path")

That's&hellip; not what we wanted at all. Even worse, some websites are coming
back as `nil/nil`. So what's going on here?

Turns out, not only is the user's `websiteURL` property an implicitly
unwrapped optional, but the `host` and `path` properties on `NSURL` are
bridged into optionals as well. If we decided to use `if let` here, we'd end
up with the following:

```swift
var website: String {
    if let url = user.websiteURL {
      if let host = url.host {
          if let path = url.path {
            return "\(host)/\(path)"
          }
      }
    }

    return ""
}
```

Again, to my eye those nested `if let` statements are ugly and hard to parse.
Luckily for us, we can use the same pattern we used before with a small
addition to handle this cleanly.

## Enter, apply

The function `apply` (represented with the infix operator `<*>` in Haskell,
and defined in Swift by us as the same) can be implemented as so:

```swift
infix operator <*> { associativity left }

func <*><A, B>(f: (A -> B)?, a: A?) -> B? {
    switch f {
    case .Some(let fx): return fx <^> a
    case .None: return .None
    }
}
```

It's very similar to our implementation of `fmap`. In fact, it even uses
`fmap` in the implementation. The main difference here is that the function
itself is an optional. Yes, that's right, functions can be optional values
just like anything else. Wild, right?

So walking through our implementation of `apply`, it works much like `fmap`,
except that we're pattern matching on the function optional (`f`), not the
normal optional value (`a`). If we have a function, we return the result of
`fmap`ing the function over `a`. Remember that this itself will then check to
see if `a` exists. If `f` is `.None`, we return `.None`.

The cool thing about this is that it allows us to chain things together in a
way that means when one thing fails (returns `.None`), everything else fails
down the line.

So how can we use this? Much like the original solution, we will create a
function to hold onto that formatting code, but this time we'll implement the
function in [curried form][delicious-curry], which allows for partial
application:

[delicious-curry]: http://www.haskell.org/haskellwiki/Currying

```swift
private func websiteFormat(host: String)(path: String) -> String {
    return "\(host)\(path)"
}
```

Notice that each argument is in its own set of parens. That's the important
part here. With this syntax, when we give the `websiteFormat` function the
`host` argument, it actually returns a new function that takes the `path`
argument. When we hand this new function the `path` argument, it satisfies all
of the required arguments, and returns the string we expect.

So now, we can take our `fmap` pattern from before and use `apply` to chain it
together with the second argument:

```swift
var website: String {
    let url = user.websiteURL
    let websiteString = websiteFormat <^> url?.host <*> url?.path
    return websiteString ?? ""
}
```

We create a local variable `url`. It's typed as `NSURL!`, but we're going to
treat it like a full blown optional.

We use `fmap` and `apply` to partially apply `websiteFormat` to the `host`,
and then if that succeeds, we pass in the `path`. If that succeeds as well, we
get `.Some` with a nicely formatted string. If it fails, we get `.None`.

We then use the `??` operator to return the value, or an empty string.

I think that looks significantly nicer than those earlier nested `if let`
statements. And we don't have to check for `.None` when accessing `url`
because we're using the [optional chaining][apple-optional-chaining] syntax.
So if `url` is `.None` this whole thing results in `.None` and we return an
empty string.

[apple-optional-chaining]: https://developer.apple.com/librarY/prerelease/mac/documentation/Swift/Conceptual/Swift_Programming_Language/OptionalChaining.html

## Wrap up

Even outside of the scope of amazing type-safe <abbr title="JavaScript Object
Notation">JSON</abbr> parsing, these concepts from Functional Programming can
make our life dealing with ubiquitous optional values just as safe (if not
safer) than when we could message `nil` all we wanted.

## What's next

Read my colleague Tony's posts on using these same concepts (and a few others)
for parsing <abbr title="JavaScript Object Notation">JSON</abbr> values safely
and cleanly.

- [Efficient JSON in Swift with Functional Concepts and Generics](https://thoughtbot.com/blog/efficient-json-in-swift-with-functional-concepts-and-generics)
- [Real World JSON Parsing with Swift](https://thoughtbot.com/blog/real-world-json-parsing-with-swift)
- [Parsing Embedded JSON and Arrays in Swift](https://thoughtbot.com/blog/parsing-embedded-json-and-arrays-in-swift)

Also, check out [Argo], the <abbr title="JavaScript Object Notation">JSON</abbr>
parsing library that was developed alongside those posts.

[Argo]: https://github.com/thoughtbot/argo
