Created
April 30, 2017 19:29
-
-
Save chriseidhof/c3918e870efae00eb3c1565ff6a9f289 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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)") } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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