継続とは? def add(i: Int, j: Int): Int = i + j def mul(i: Int, j: Int): Int = i * j def show(i: Int): String = s"num: $i" val a = add(1, 2) val b = mul(a, 3) val s = show(b) println(s)
継続とは? def add(i: Int, j: Int): Int = i + j def mul(i: Int, j: Int): Int = i * j def show(i: Int): String = s"num: $i" val a = add(1, 2) // 計算結果 // その後の計算 val b = mul(a, 3) val s = show(b) println(s)
継続とは? def add(i: Int, j: Int): Int = i + j def mul(i: Int, j: Int): Int = i * j def show(i: Int): String = s"num: $i" val a = add(1, 2) val b = mul(a, 3) // 計算結果 // その後の計算 val s = show(b) println(s)
継続とは? def add(i: Int, j: Int): Int = i + j def mul(i: Int, j: Int): Int = i * j def show(i: Int): String = s"num: $i" val a = add(1, 2) val b = mul(a, 3) val s = show(b) // 計算結果 // その後の計算 println(s)
継続渡しスタイル // 直接スタイル(再掲) val a = add(1, 2) val b = mul(a, 3) val s = show(b) println(s) // 継続渡しスタイル add(1, 2){ a => mul(a, 3){ b => show(b){ s => println(s) } } }
継続を値として扱う def add[R](i: Int, j: Int)(cont: Int => R): R = { val a = i + j cont(a) } def show[R](i: Int)(cont: String => R): R = { val a = s"num: $i" cont(a) }
継続を値として扱う def add[R](i: Int, j: Int)(cont: Int => R): R = { val a = i + j cont(a) } def show[R](i: Int)(cont: String => R): R = { val a = s"num: $i" cont(a) }
継続モナドを for 式で合成する def prog[R]: Cont[R, String] = for { a b s } yield { s.toUpperCase } def prog[R]: Cont[R, String] = add(1, 2).flatMap { a => mul(a, 3).flatMap { b => show(b).map { s => s.toUpperCase } } } :Cont[R, A] { ar => ??? } の ar に渡される関数 ※厳密には ar には run の引数も含まれる
継続モナドを for 式で合成する def prog[R]: Cont[R, String] = for { a b s } yield { s.toUpperCase } def prog[R]: Cont[R, String] = add(1, 2).flatMap { a => mul(a, 3).flatMap { b => show(b).map { s => s.toUpperCase } } } :Cont[R, A] { ar => ??? } の ar に渡される関数 ※厳密には ar には run の引数も含まれる
継続モナドを for 式で合成する def prog[R]: Cont[R, String] = for { a b s } yield { s.toUpperCase } def prog[R]: Cont[R, String] = add(1, 2).flatMap { a => mul(a, 3).flatMap { b => show(b).map { s => s.toUpperCase } } } :Cont[R, A] { ar => ??? } の ar に渡される関数 ※厳密には ar には run の引数も含まれる
活用する際の注意点 - 実行回数 val prog: Cont[Unit, Unit] = for { _ _ } yield () // めでたく二回実行されてしまいました scala> prog.run(identity) insert data to database insert data to database