Skip to content
/ Monoid Public

A binary operation meets an identity element, much fun ensues…

License

Notifications You must be signed in to change notification settings

alskipp/Monoid

Repository files navigation

Monoid

Build Status Carthage compatible Swift 3.0

An implementation of Monoids in Swift. I'll add more explanation at some point, but for now, let's jump straight to a practical example: Sorting.

Take a look at the data structure below. (If you're keen to test out the code, there's a Playground included with the project).

struct PersonData {
  let name: String, age: Int, height: Double, weight: Double
}

let records = [
  PersonData(name: "Fred", age: 50, height: 170, weight: 65),
  PersonData(name: "Jane", age: 50, height: 170, weight: 52),
  PersonData(name: "Nora", age: 30, height: 180, weight: 65),
  PersonData(name: "Paul", age: 34, height: 100, weight: 50),
  PersonData(name: "Gill", age: 10, height: 105, weight: 35), // identical twins
  PersonData(name: "Bill", age: 10, height: 105, weight: 35)  // identical twins
]

The challenge is to sort an Array of this data by multiple properties. Sort first by, height then weight then age then name.

Here's how it looks using the Ordering Monoid:

let sortedRecords = records.sortBy { x, y in
  comparing(x, y) { $0.height } <>
  comparing(x, y) { $0.weight } <>
  comparing(x, y) { $0.age } <>
  comparing(x, y) { $0.name }
}

And here's a version without:

let sortedRecords2 = records.sort { x, y in
  if x.height == y.height {
    if x.weight == y.weight {
      if x.age == y.age {
        return x.name < y.name
      } else {
        return x.age < y.age
      }
    } else {
      return x.weight < y.weight
    }
  } else {
    return x.height < y.height
  }
}

There are many more Monoids defined in the project with examples in the Xcode Playground file, so please take a look.

Current limitations

Using Swift 3, it is not possible to define various Monoids. Such as:

extension Optional: Monoid where Wrapped: Monoid {}
error: extension of type 'Optional' with constraints cannot have an inheritance clause

Which is the same restriction that prevents making Array Equatable with:

extension Array: Equatable where Element: Equatable {}

There's a chance that this will be possible with Swift 4, or maybe even Swift 3.1 – one can hope.

Another limitation is the inability to extend Tuples, though whether this limitation will be removed in Swift, I'm not sure. Despite these current limitations I think it's still worth while just to get the Ordering Monoid.

About

A binary operation meets an identity element, much fun ensues…

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published