FWIW, there is a way to solve the issue without introducing an optional in many cases. We could introduce a Monoid
protocol:
protocol Monoid {
associatedtype Value
/// must obey identity laws with respect to `combine`
static var identity: Value
/// must be associative
static func combine(_ lhs: Value, _ rhs: Value) -> Value
}
With conformances such as:
extension Int {
enum Add: Monoid {
static var identity = 0
static func combine(_ lhs: Int, _ rhs: Int) { return lhs + rhs }
}
enum Multiply: Monoid {
static var identity = 1
static func combine(_ lhs: Int, _ rhs: Int) { return lhs * rhs }
}
}
and this overload of fold
:
public func fold<M: Monoid>(_ Monoid.Type) -> Element where M.Value == Element
which would then be called as follows:
let sum: Int = sequenceOfInt.fold(Add.self)