If you are unfamiliar with Semigroups & Monoids please read my previous article first.

A Semigroup has an appending <> operation.

A Semiring has two appending operations, plus ( + ) and times ( * ), and two respective identity elements, zero and one .

Rules

Addition must return the same value regardless of the order of values. This is known as a commutative monoid.

return the same value regardless of the order of values. This is known as a commutative monoid. Multiplication by zero must return zero . This is often referred to as annihilation.

return . This is often referred to as annihilation. Standard rules apply for + and * in terms of associativity

Based on this description, we can write a protocol like so:

protocol Semiring {

static func + (lhs: Self, rhs: Self) -> Self

static func * (lhs: Self, rhs: Self) -> Self

static var zero: Self { get }

static var one: Self { get }

}

Now lets see how this might work with a Int type.

extension Int: Semiring {

static let zero = 0

static let one = 1

}

We get the + and * behaviour for free in this case.

Not very exciting yet I admit, we haven’t done anything that the standard Swift framework doesn’t already provide.

We can also extend Bool with the Semiring protocol which will be useful for our example below…

extension Bool: Semiring {

static func + (lhs: Bool, rhs: Bool) -> Bool {

return lhs || rhs

} static func * (lhs: Bool, rhs: Bool) -> Bool {

return lhs && rhs

} static let zero = false

static let one = true

}

This one is a little different. We can state that:

+ is the same as || since ( true || false = true ) and ( false || true = true ) — passing the first rule

is the same as since ( = ) and ( ) — passing the first rule * is the same as && ( true && false = false ) — passing the second rule

So now we have the ability to combine boolean values with + and * .

Still not very exciting, so let’s create a structure that wraps a lambda.

Here is the implementation:

struct Function<A, B> {

let execute: (A) -> B

}

Now we have the ability of making a Function a Semiring like so:

extension Function: Semiring where B: Semiring {

static func + (lhs: Function, rhs: Function) -> Function {

return Function { lhs.execute($0) + rhs.execute($0) }

} static func * (lhs: Function, rhs: Function) -> Function {

return Function { lhs.execute($0) * rhs.execute($0) }

} static var zero: Function {

return Function { _ in S.zero }

} static var one: Function {

return Function { _ in S.one }

}

}

The above operators are basically taking two Function objects and applying the ( A ) value to each to return ( B1 and B2 ) and then applying the operator between both ( B1 +/* B2 ).

In order to return zero and one values we can just return whatever our S value defines these values as. Simple.