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)) } } } }