1 import Foundation 2 3 /// A semigroup is an algebraic structure that consists of a set of values and an associative operation. 4 public protocol Semigroup { 5 6 /// An associative operation to combine values of the implementing type. 7 /// 8 /// This operation must satisfy the semigroup laws: 9 /// 10 /// a.combine(b).combine(c) == a.combine(b.combine(c)) 11 /// 12 /// - Parameter other: Value to combine with the receiver. 13 /// - Returns: Combination of the receiver value with the parameter value. 14 func combine(_ other: Self) -> Self 15 } 16 17 // MARK: - Semigroup syntax 18 public extension Semigroup { 19 /// Combines two values of the implementing type. 20 /// 21 /// - Parameters: 22 /// - a: Value of the implementing type. 23 /// - b: Value of the implementing type. 24 /// - Returns: Combination of `a` and `b`. 25 0 static func combine(_ a: Self, _ b: Self) -> Self { 26 0 return a.combine(b) 27 } 28 29 /// Combines a variable number of values of the implementing type, in the order provided in the call. 30 /// 31 /// - Parameter elems: Values of the implementing type. 32 /// - Returns: A single value of the implementing type representing the combination of all the parameter values. 33 1 static func combineAll(_ elems: Self...) -> Self { 34 1 return combineAll(elems) 35 } 36 37 /// Combines an array of values of the implementing type, in the order provided in the call. 38 /// 39 /// - Parameter elems: Array of values of the implementing type. 40 /// - Returns: A single value of the implementing type representing the combination of all the parameter values. 41 1 static func combineAll(_ elems: [Self]) -> Self { 42 1 return elems[1 ..< elems.count].reduce(elems[0], { partial, next in partial.combine(next) }) 43 } 44 }

Read our documentation on viewing source code .