Skip to content

Instantly share code, notes, and snippets.

@JadenGeller
Last active July 18, 2017 23:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JadenGeller/a1c631866c19c8701c19b10a8364932d to your computer and use it in GitHub Desktop.
Save JadenGeller/a1c631866c19c8701c19b10a8364932d to your computer and use it in GitHub Desktop.
Mean Monoid
infix operator ☹: AdditionPrecedence
struct Mean: ExpressibleByFloatLiteral, ExpressibleByIntegerLiteral {
private let total: Float
private let count: Int
private init(total: Float, count: Int) {
self.total = total
self.count = count
}
public var averageValue: Float {
return total / Float(count)
}
public init(floatLiteral value: Float) {
self.total = value
self.count = 1
}
public init(integerLiteral value: Int) {
self.init(floatLiteral: Float(value))
}
// Associative operation
public static func ☹(lhs: Mean, rhs: Mean) -> Mean {
return Mean(
total: lhs.total + rhs.total,
count: lhs.count + rhs.count
)
}
// Identity element
public static var identity = Mean(total: 0, count: 0)
}
print((1 ☹ 2 ☹ 3 ☹ 4).averageValue) // -> 2.5
print((Mean.identity).averageValue) // -> nan
print((1 ☹ Mean.identity ☹ 2 ☹ 3 ☹ 4).averageValue) // -> 2.5
// Monoids are useful for incremental computation
var result: Mean = .identity
for x in [1, 2, 3, 4] {
result = result ☹ Mean(x)
}
print(result.averageValue) // -> 2.5
// We can even do half of the computation on another machine
// and then combine both results later!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment