A video series exploring functional programming and Swift.
#52 • Monday Apr 1, 2019 • Subscriber-only

Enum Properties

Swift makes it easy for us to access the data inside a struct via dot-syntax and key-paths, but enums are provided no such affordances. This week we correct that deficiency by defining the concept of “enum properties”, which will give us an expressive way to dive deep into the data inside our enums.

This episode builds on concepts introduced previously:

#52 • Monday Apr 1, 2019 • Subscriber-only

Enum Properties

Swift makes it easy for us to access the data inside a struct via dot-syntax and key-paths, but enums are provided no such affordances. This week we correct that deficiency by defining the concept of “enum properties”, which will give us an expressive way to dive deep into the data inside our enums.

This episode builds on concepts introduced previously:


Subscribe to Point‑Free

This episode is for subscribers only. To access it, and all past and future episodes, become a subscriber today!

See subscription optionsorLog in

Sign up for our weekly newsletter to be notified of new episodes, and unlock access to any subscriber-only episode of your choosing!

Sign up for free episode

Introduction

Last time we revisited a topic that we know and love: algebraic data types. We explored how in the Swift type system Swift, multiplication manifests itself in product types, like structs and tuples, and addition manifests itself in sum types, like enums. We saw that, just like in algebra, addition and multiplication, and structs and enums are just two sides of the same coin: no one is more important than the other. And we saw that many of the things we love about structs do in fact have a corresponding feature on enums, and vice versa.

However, we also saw that product types definitely see some favoritism over enums in the language design. We saw this especially in how Swift gives us anonymous structs in the form of tuples, but there is no corresponding anonymous enum type. We theorized how it might look and we may even have it in the language some day because it’d be a really nice tool to have.

Now anonymous sum types isn’t something we can fix ourselves, but there are other examples of struct favoritism that we can correct by bringing enums up to the same level.

Subscribe to Point-Free

👋 Hey there! Does this episode sound interesting? Well, then you may want to subscribe so that you get access to this episodes and more!


Exercises

  1. While we’ve defined the gets of our enum properties, we haven’t defined our sets. Redefine Validated’s valid and invalid properties to have a setter in addition to its getter.

    Solution

    We can redefine valid with the following setter.

    var valid: Valid? {
      get {
        guard
          case let .valid(value) = self
          else { return nil }
        return value
      }
      set {
        guard
          let newValue = newValue,
          case .valid = self
          else { return }
        self = .valid(newValue)
      }
    }
    

    While we must safely unwrap a non-optional newValue to reassign self, we also test that the current self is valid before doing so.

    The invalid property is the same boilerplate but uses the invalid case.

    var invalid: [Invalid]? {
      get {
        guard
          case let .invalid(value) = self
          else { return nil }
        return value
      }
      set {
        guard
          let newValue = newValue,
          case .invalid = self
          else { return }
        self = .invalid(newValue)
      }
    }
    
  2. Take the valid setter for a spin. Assign Validated<Int, String>.valid(1) to a variable and increment the number using the setter.

    Solution

    There are a few ways of doing this! First, let’s assign a mutable variable.

    var v = Validated<Int, String>.valid(1)
    

    We can map over the optional Int returned by the valid getter.

    v.valid = v.valid.map { $0 + 1 }
    

    Or we can optionally chain with the += operator.

    v.valid? += 1
    

References

Chapters
Introduction
00:05
Accessing product and sum data
01:24
Arrays of enums
06:52
Structs and key paths
11:45
Accessing Result data
13:29
Recovering enum ergonomics
17:09
What’s the point?
22:06