Skip to content

Instantly share code, notes, and snippets.

@alskipp
Last active February 3, 2018 22:56
Show Gist options
  • Select an option

  • Save alskipp/3fd25ee9a92bba329b2f to your computer and use it in GitHub Desktop.

Select an option

Save alskipp/3fd25ee9a92bba329b2f to your computer and use it in GitHub Desktop.
Swiftly towards the monoid
// erm… this Num protocol is useless, but let's overlook this bit for now, shall we?
protocol Num: IntegerLiteralConvertible, IntegerArithmeticType {}
extension Int: Num {}
protocol Monoid {
typealias t
static func mempty() -> t
static func mappend(a: t, _ b: t) -> t
static func mconcat(a: [t]) -> t
}
extension Monoid {
static func mconcat(a: [t]) -> t {
return a.reduce(mempty(), combine: mappend)
}
}
extension Array: Monoid {
static func mempty() -> [Element] {
return []
}
static func mappend(a: [Element], _ b: [Element]) -> [Element] {
return a + b
}
}
struct Sum<T: Num> {
let value: T
init(_ v: T) { value = v }
}
extension Sum: Monoid {
static func mempty() -> Sum<T> {
return Sum(0)
}
static func mappend(a: Sum<T>, _ b: Sum<T>) -> Sum<T> {
return Sum(a.value + b.value)
}
}
struct Product<T: Num> {
let value: T
init(_ v: T) { value = v }
}
extension Product: Monoid {
static func mempty() -> Product<T> {
return Product(1)
}
static func mappend(a: Product<T>, _ b: Product<T>) -> Product<T> {
return Product(a.value * b.value)
}
}
let a1: [Int] = .mempty() // []
let a2: [Int] = .mappend([1,2],[3,4,5]) // [1,2,3,4,5]
let a3: [Int] = .mconcat([[1,2],[3],[4,5]]) // [1,2,3,4,5]
let s1: Sum<Int> = .mempty()
s1.value // 0
let s2: Sum = .mappend(Sum(1), Sum(2))
s2.value // 3
let s3: Sum = .mconcat([1,2,3,4,5].map(Sum.init))
s3.value // 15
let p1: Product<Int> = .mempty()
p1.value // 1
let p2: Product = .mappend(Product(2), Product(3))
p2.value // 6
let p3: Product = .mconcat([1,2,3,4,5].map(Product.init))
p3.value // 120
@alskipp
Copy link
Author

alskipp commented Jul 28, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment