Skip to content

Instantly share code, notes, and snippets.

@chriseidhof
Created April 30, 2017 19:29
Show Gist options
  • Save chriseidhof/c3918e870efae00eb3c1565ff6a9f289 to your computer and use it in GitHub Desktop.
Save chriseidhof/c3918e870efae00eb3c1565ff6a9f289 to your computer and use it in GitHub Desktop.
// effect Choice {
// operation decide() -> Bool
// }
// This is not polymorphic over the `Result`,
protocol Choice {
associatedtype Result
associatedtype State
func decide(_ k: (Bool, @escaping (State) -> ()) -> (), next: @escaping (Result) -> ())
func val(_ x: Result) -> State
}
struct ChooseAll<B>: Choice {
func decide(_ k: (Bool, @escaping ([B]) -> ()) -> (), next: @escaping (B) -> ()) {
var result: [B] = []
k(true, { result.append(contentsOf:$0) })
k(false, { result.append(contentsOf:$0) })
result.forEach(next)
}
func val(_ x: B) -> [B] {
return [x]
}
}
struct ChooseFirst<B>: Choice {
func decide(_ k: (Bool, @escaping (B) -> ()) -> (), next: @escaping (B) -> ()) {
var result: [B] = []
k(true, next)
}
func val(_ x: B) -> B {
return x
}
}
func algo<C>(_ c: C, callback: @escaping (Int) -> ()) where C: Choice, C.Result == Int {
c.decide({ b1, next in
next(b1 ? c.val(10) : c.val(20))
}, next: { x in
c.decide({ b2, next in
next(b2 ? c.val(0) : c.val(5))
}, next: { y in
callback(x - y)
})
})
}
var c1 = ChooseAll<Int>()
var c2 = ChooseFirst<Int>()
algo(c1) { print("c1: \($0)") }
algo(c2) { print("c2: \($0)") }
// effect Choice {
// operation decide() -> Bool
// }
struct ChooseAll {
func decide<B>(_ k: (Bool, @escaping ([B]) -> ()) -> (), next: @escaping (B) -> ()) {
var result: [B] = []
k(true, { result.append(contentsOf:$0) })
k(false, { result.append(contentsOf:$0) })
result.forEach(next)
}
func val<A>(_ x: A) -> [A] {
return [x]
}
}
var c = ChooseAll()
c.decide({ b1, next in
next(b1 ? c.val(10) : c.val(20))
}, next: { x in
c.decide({ b2, next in
next(b2 ? c.val(0) : c.val(5))
}, next: { y in
print("c: \(x - y)")
})
})
struct ChooseFirst {
func decide<B>(_ k: (Bool, @escaping (B) -> ()) -> (), next: @escaping (B) -> ()) {
var result: [B] = []
k(true, next)
}
func val<A>(_ x: A) -> A {
return x
}
}
var c2 = ChooseFirst()
c2.decide({ b1, next in
next(b1 ? c2.val(10) : c2.val(20))
}, next: { x in
c2.decide({ b2, next in
next(b2 ? c2.val(0) : c2.val(5))
}, next: { y in
print("c2: \(x - y)")
})
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment