Skip to content

Instantly share code, notes, and snippets.

@bkase
Created January 5, 2018 06:08
Show Gist options
  • Save bkase/3023de27e70721d55fdf689cc4545c48 to your computer and use it in GitHub Desktop.
Save bkase/3023de27e70721d55fdf689cc4545c48 to your computer and use it in GitHub Desktop.
Monoidal Cancellations (ported from Swift Sandbox)
// Write some awesome Swift code, or import libraries like "Foundation",
// "Dispatch", or "Glibc"
struct Monoid<T> {
let empty: T
let append: (T, T) -> T
func fold(_ arr: [T]) -> T {
return arr.reduce(empty, append)
}
func foldMap<R>(_ arr: [R], _ f: (R) -> T) -> T {
return fold(arr.map(f))
}
}
// TODO: Atomic this
func once(_ f: @escaping () -> ()) -> () -> () {
var ran = false
return {
if !ran {
f()
ran = true
}
}
}
struct CancelToken {
static let monoid: Monoid<CancelToken> =
Monoid(empty: CancelToken(cancel: {}), append: { f, g in
CancelToken(cancel: { f.cancel(); g.cancel() })
})
private let fn: () -> ()
init(cancel: @escaping () -> ()) {
self.fn = once(cancel)
}
func cancel() {
fn()
}
}
let c1 = CancelToken(cancel: { print("cancel 1") })
let c2 = CancelToken(cancel: { print("cancel 2") })
CancelToken.monoid.fold([c1, c2, c1, c2]).cancel()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment