Discriminated Unions in Swift

In Swift, enumerations have built in support for Discriminated Unions through what they call Associated Values.

From MSDN:

Discriminated unions provide support for values that can be one of a number of named cases, possibly each with different values and types. Discriminated unions are useful for heterogeneous data; data that can have special cases, including valid and error cases; data that varies in type from one instance to another; and as an alternative for small object hierarchies. In addition, recursive discriminated unions are used to represent tree data structures.

A discriminated union is a simpler alternative to a small object hierarchy. For example, the following discriminated union could be used instead of a Shape base class that has derived types for circle, square, and so on.

import Darwin

enum Shape {
  case Rectangle(Double, Double)
  case Circle(Double)
  case Square(Double)
  case EquilateralTriangle(Double)

  var area : Double {
    case .Rectangle(let w, let h): return w * h
    case .Circle(let r):  return M_PI * r * r
    case .Square(let x):  return x * x
    case .EquilateralTriangle(let s): return sqrt(3.0) / 4.0 * s * s

The area of a rectangle is:

let s1 = Shape.Rectangle(10, 20)
println(s1.area) //Output: 200.0

Coming Soon: Recursion

Recursive Discriminated Unions (where an associated value is the enum itself) can be used for tree structures. It’s unclear if Swift supports such recursion because the REPL crashes with a segmentation fault. We’ll post an update when more information is available.

Recursion looks like this:

enum Tree {
  case Tip
  case Node(Int, Tree, Tree)

  var sumTree: Int {
    switch self {
      case .Tip: return 0
      case let .Node(value, left, right): return value + left.sumTree + right.sumTree

let tree = Tree.Node(0, Tree.Node(1, Tree.Tip, Tree.Tip), Tree.Node(3, Tree.Tip, Tree.Tip)), Tree.Node(4, Tree.Tip, Tree.Tip))
println(tree.sumTree) //Output: 10

The example above creates this tree:

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s