/// A two-dimensional matrix of memoized values. /// /// These values are populated by a function from the coordinates of a given cell to the matrix’s element type. /// /// Values are retrieved by subscripting with row/column indices. Out-of-bound indices produce `nil` values, rather than asserting. public struct Matrix { public init(width: Int, height: Int, compute: (Int, Int) -> A) { self.init(width: width, height: height, values: constructRowMajor(width, height: height, forEach: { i, j in Memo { compute(i, j) } })) } public let width: Int public let height: Int private let values: [Memo] public subscript (i: Int, j: Int) -> Memo? { guard i < width && j < height else { return nil } return values[i + j * width] } // MARK: Functor public func map(transform: A -> Other) -> Matrix { return Matrix(width: width, height: height, values: values.map { $0.map(transform) }) } // MARK: Implementation details private init(width: Int, height: Int, values: [Memo]) { self.width = width self.height = height self.values = values } } /// Constructs a row-major ordering of values produced with `forEach`. private func constructRowMajor(width: Int, height: Int, @noescape forEach: (Int, Int) -> A) -> [A] { var values: [A] = [] values.reserveCapacity(width * height) for j in 0..