Skip to content

Instantly share code, notes, and snippets.

@CodaFi
Created October 5, 2014 02:54
Show Gist options
  • Save CodaFi/2186a73bdfb9fff79c26 to your computer and use it in GitHub Desktop.
Save CodaFi/2186a73bdfb9fff79c26 to your computer and use it in GitHub Desktop.
A Swift Continuation Monad
// Playground - noun: a place where people can play
public func id<A>(x : A) -> A {
return x
}
public func error<A>(x : String) -> A {
assert(false, x)
}
/// The Continuation Monad
public struct Cont<R, A> {
let run : (A -> R) -> R
init(_ run : (A -> R) -> R) {
self.run = run
}
public static func pure(a : A) -> Cont<R, A> {
return Cont({ f in f(a) })
}
}
public func bind<R, A, B>(c : Cont<R, A>, f : A -> Cont<R, B>) -> Cont<R, B> {
return Cont({ k in c.run({ a in f(a).run(k) }) })
}
public func fmap<R, A, B>(c : Cont<R, A>, f : A -> B) -> Cont<R, B> {
return Cont({ k in c.run({ a in k(f(a)) }) })
}
public func callcc<R, A, B>(f : (A -> Cont<R, B>) -> Cont<R, A> ) -> Cont<R, A> {
return Cont({ k in f({ a in Cont({ x in k(a) }) }).run(k) })
}
// Examples from http://tonymorris.github.io/blog/posts/continuation-monad-in-scala/
public func square(n : Int) -> Int {
return n * n
}
public func squarec<R>(n : Int) -> Cont<R, Int> {
return Cont<R, Int>.pure(square(n))
}
public func squareE(n : Int) -> Cont<(), Int> {
return squarec(n)
}
squareE(6)
public func div<R>(c : String -> Cont<R, Int>, n : Int, d : Int) -> Cont<R, Int> {
return callcc({ ok in bind(callcc({ err in d == 0 ? err("Denominator 0") : ok(n / d) }), c) })
}
public func divError<R>(n : Int, d : Int) -> Cont<R, Int> {
return div({ s in return error(s) }, n, d)
}
divError(7, 3).run(println)
divError(7, 0).run(println)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment