D -> R) -> A -> R { return { a in return fCPS({ b in return gCPS({ c in return hCPS({ d in return completion(d) })(c) })(b) })(a) } } // fooCPS(completion) == fCPS(gCPS(hCPS(completion))) /05&͜ͷܗ "%ʹର͢Δ$14
func cpsTransform<X, Y, R>(_ xToY: X -> Y) -> (Y -> R) -> (X -> R) { return { yToR in return { x in yToR(xToY(x)) } } } let f: A -> B = ... let fCPS: (B -> R) -> (A -> R) = cpsTransform(f) let g: B -> C = ... let gCPS: (C -> R) -> (B -> R) = cpsTransform(g) let h: C -> D = ... let hCPS: (D -> R) -> (C -> R) = cpsTransform(h) let foo: A -> D = { a in h(g(f(a))) } let fooCPS: (D -> R) -> (A -> R) = { k in fCPS(gCPS(hCPS(k))) } $14มʹΑΓ ඌ࠶ؼ࠷దԽͳͲ͕ߦ͑Δ
-> F<R> ≅ F<A> ʹ F = ߃ؔख Λద༻ͨ͠ͱ͖ͷࠨลɻ struct Cont<R, A> { let run: (A -> R) -> R } extension Monad[Cont<R, _>] { func flatMap<B>(_ f: A -> Cont<R, B>) -> Cont<R, B> { Cont<R, B> { k in self.run { a in f(a).run(k) } } } }
B, C>(retain value: IO<A>, release: A -> IO<B>) -> Cont<IO<C>, A> { Cont { k in value.flatMap { a in k(a).flatMapError { _ in release(a) } .flatMap { r in release(a).map { _ in r } } } } }
let resume: M<State> indirect enum State { case done(A) // AΛฦͯ͠ऴྃ͢ΔλεΫ case suspended(F<Coroutine<F, M, A>>) // F ʹแ·Ε͍ͯΔɺதஅ͞ΕͨλεΫ } } extension Monad[Coroutine<F, M, _>] where Functor[F], Monad[M] { func flatMap<B>(_ f: A -> Coroutine<F, M, B>) -> Coroutine<F, M, B> { self.resume.flatMap { state in switch state { case let .done(a): return f(a).resume case let .suspended(fco): return M.unit(.suspended(fco.map { $0.flatMap(f) })) } } } } લճͷࣗ༝Ϟφυ'SFF' "ʹ ෭࡞༻.͕Ճ͞Εͨܗ ࣗ༝Ϟφυมࢠ
A>(_ fco: F<Coroutine<F, M, A>>) -> Coroutine<F, M, A> where Functor[F], Monad[M] { Coroutine(M.unit(.suspended(fco))) } /// ෭࡞༻ M Λίϧʔνϯʹม func lift<F, M, A>(_ effect: M<A>) -> Coroutine<F, M, A> where Functor[F], Monad[M] { Coroutine(effect.map(.done)) }
{ static func zipWith(_ f: A -> B -> C) -> Coroutine<F, M, A> -> Coroutine<F, M, B> -> Coroutine<F, M, C> { { coroutineA in { coroutineB in coroutineA.flatMap { a in coroutineB.flatMap { b in .unit(f(a)(b)) } } } } } } func runCoroutines<M, A>(_ pauses: [Pause<M, A>]) -> M<[A]> where Monad[M] { func run(_ pause: Pause<M, A>) -> M<A> where Monad[M] { pause.resume.flatMap { state in switch state in { case let .done(arr): return M.unit(arr) case let .suspended(fco): return run(fco.next) } } } let combined = pauses.reduce(Pause.unit([])) { acc, pause in Pause.zipWith({ [$0] + $1 })(pause)(acc) } return run(combined) } ྻͷ[JQͱߟ͑ํಉ͡ ͭͷ$PSPVUJOFΛʮ$14ͷྻʯ ʹݟཱͯɺ$14ϖΞͷྻΛ࡞Δ ͜͜Ͱ͞ΒʹGͰϖΞΛ$ʹม͢Δ $14ϖΞͷྻΛ ʮڠௐతʯʹ࣮ߦ͢Δ
-> Next } // Iteratee ͱݺΕΔ typealias Receive<Money, M, A> = Coroutine<ReceiveF<Money>, M, A> // NOTE: receiveॲཧʹ suspend ͕ؔΘΕΔ func receive<Money>() -> Receive<Money, M, Money> where Monad[M] { suspend(ReceiveF(.unit)) }
money send(money) } let receiver = Receive.do { money <- receive() accountB += money } runCoroutines(sender, receiver) // ༨ஊɿrunCoroutine ͷத (NOTE: fatalError ΛΘͳ͍Ͱ͖Δ) func runCoroutines<Money, M, A, B>(sender: Send<Money, M, A>, receiver: Receive<Money, M, B>) -> M<(A, B)> where Monad[M] { sender.resume.flatMap { sent in receiver.resume.flatMap { received in switch (sent, received) { case let (.done(a), .done(b)): return .unit((a, b)) case let (.done(a), .suspended(fco)): fatalError("sender ended too soon") case let (.suspended(a, co), .done(b)): return runCoroutines(co, .unit(b)) case let (.suspended(a, co), .suspended(f)): return runCoroutines(co, f(a)) } } } }
interfacing async tasks with synchronous code • SE-0304 Structured concurrency • SE-0317 async let bindings • Swift concurrency: Behind the scenes - WWDC21 • Explore structured concurrency in Swift - WWDC21 • Meet async/await in Swift - WWDC21 • Coroutines in LLVM • Zewo/Venice • belozierov/SwiftCoroutine • Swift Language Updates - Learn Languages 2021
| haskell • Free Monad | haskell • A Neighborhood of Infinity: The Mother of all Monads • The Comonad.Reader » Free Monads for Less (Part 1 of 3): Codensity • Eugenio Moggi. 1991. Notions of computation and monads • Philip Wadler. 1994. Monads and composable continuations • Philip Wadler. 1995. Monads for functional programming • Gordon Plotkin and John Power. 2002. Notions of Computation Determine Monads • W Swierstra. 2008. Data types a la carte. • Janis Voigtländer. 2008. Asymptotic Improvement of Computations over Free Monads • O Kiselyov, A Sabry, C Swords. 2013. Extensible effects: an alternative to monad transformers • E Rivas and M Jaskelioff. 2017. Notions of computation as monoids.
for an open world • continuation-passing style in nLab • ܧଓ | haskell • ܧଓ͠ͳHaskellϥΠϑ - ϞφυͱΘͨ͠ ͱίϞφυ • ܧଓϞφυʹΑΔϦιʔεཧ - Qiita • Scala ʹ͓͚ΔܧଓϞφυͷ࣮ͱ׆༻ - Speaker Deck • Deep Dive async/await in Unity with UniTask(UniRx.Async) • ฒߦϓϩάϥϛϯάͱܧଓϞφυ • ઙҪ ݈Ұ. shift/reset ϓϩάϥϛϯάೖ • Kenichi Asai. 2009. On typing delimited continuations: three new solutions to the printf problem • Continuations and Delimited Control • The Monad.Reader/Issue2/ FunWithLinearImplicitParameters
concurrency, or: Go statement considered harmful — njs blog • Structured concurrency | by Roman Elizarov | Medium • Roman Elizarov — Structured concurrency - YouTube
Issue 19 • CoroutineϞφυͱεςʔτϚγϯ - The curse of λ • stackfulness of coroutines - lilyum ensemble • Introduction to the C++ coroutines | C++ - don't panic! • 20͘Β͍ͰΘ͔ͬͨؾʹͳΕΔC++20ίϧʔ νϯ • Coroutines guide | Kotlin • 2016 LLVM Developers’ Meeting: G. Nishanov “LLVM Coroutines” - YouTube • 2018 LLVM Developers’ Meeting: J. McCall “Coroutine Representations and ABIs in LLVM” - YouTube • GeeCON 2019: Dmitry Kandalov - Coroutines explained by example - YouTube • Functorial Blog - Stackless Coroutines in PureScript • Functorial Blog - Extensible Coeffects • Roshan James and Amr Sabry. 2011. Yield: Mainstream Delimited Continuations • R. P. Pieters and T. Schrijvers. 2020. Faster Coroutine Pipelines: A Reconstruction
Duality • O Danvy, A Filinski. 1992. Representing control: A study of the CPS transformation • Andrzej Filinski. 1994. Representing Monads. • Andrzej Filinski. 1999. Representing layered monads. • Carl Bruggeman et al. 1996. Representing control in the presence of one-shot continuations • Gordon Plotkin and Matija Pretnar. 2009. Handlers of algebraic effects. • Matija Pretnar. 2015. An Introduction to Algebraic Effects and Handlers • yallop/effects-bibliography • S. Kawahara, et al. 2020. One-shot Algebraic Effects as Coroutines • ܧଓͱ͔ͷαʔϕΠ | κeenͷHappy Hacκing Blog • Ploeg & Kiselyov. 2014. Reflection without Remorse • Monadic Reflection in Haskell • ϞφυΛͭ͘Ζ͏ • Monadic Reflectionʹ͍ͭͯ - Arantium Maestum • Y. Forster, et al. 2017. On the Expressive Power of User- Defined Effects Effect Handlers, Monadic Reflection, Delimited Control. • Toru Kawata. 2018. A Contextual Reconstruction of Monadic Reflection.