1
1
mirror of https://github.com/github/semantic.git synced 2024-12-28 09:21:35 +03:00
semantic/prototype/Doubt/Matrix.swift
Rob Rix 2726a43c83 Lazily, not eagerly.
`Memo.init` selected the eager version, of course, since the lazy
version takes a closure.
2015-10-06 14:19:39 -04:00

49 lines
1.4 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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