TalkTalk has a few ways to group data. Structs define a reusable kind of value, records are handy one-off bundles of fields, and enums describe values that can be one of several cases. Patterns let you look inside all three.

Structs

A struct declares stored fields and methods. It receives a memberwise initializer when it does not declare its own init:

A custom initializer assigns fields and returns self:

Records

Records need no declaration and are typed by their fields:

Use records for local structural values and structs for nominal identity, conformance, constructors, or a public API.

Enums

Enum cases may be empty or carry values:

enum Response {
	case ok(String)
	case redirect(to: String)
	case other(Int)
}

let response = Response.ok("all good")
let redirect: Response = .redirect(to: "/login")

Case qualification can be omitted when the expected enum type is known. Payload labels are used in construction and matching.

Exhaustive matching

match is exhaustive and returns a value:

Adding a case to Response makes an old match incomplete until the new case is handled.

Patterns include literals, bindings, _, tuples, enum cases, records, structs, and alternatives:

A struct pattern names the type and may ignore remaining fields with ..:

Pattern conditions

if let tests a pattern. Comma-separated condition clauses run left to right, short-circuit, and make earlier bindings visible to later clauses:

if let .some(user) = lookup(), user.active {
	print(user.name)
}

A let ... else guard makes the successful bindings available after the statement:

GADTs (Generalized Algebraic Data Types)

A case may refine the enum's result type. This supports generalized algebraic data types:

Inside each arm, the compiler learns the result type promised by that case. That is why the Int arm can return an Int and the String arm can return a String from the same generic function.

Further reading

TalkTalk's GADTs follow the same broad idea described in Simple unification-based type inference for GADTs. The compiler combines that idea with bidirectional checking; Complete and easy bidirectional typechecking for higher-rank polymorphism is useful background.