JavaScriptでCPS
フィボナッチ関数をContinuation Passing Styleで書いてみました。
これで任意の時点で計算を止めたり後で再開したり、続けた後で戻ってみたりできるようになったはずです。
実行の処理は結局最後のwhileループが一歩ずつ進めているわけです。
なんかGUIに似てますね。
// Continuation Passing Style // Task :: take None return next Task to do function getFibTask(n, c){ function FibTask(){ if(n == 0 || n == 1){ return c(1) } // return fib(n - 1) + fin(n - 2) // means: (add(fib(n - 1)))(fin(n - 2)) function next(value){ // get fib(n - 1) function add_(x){return x + value} // partial apply function next(value){ // get fib(n - 2) return c(add_(value)) } return getFibTask(n - 2, next); } return getFibTask(n - 1, next); } return FibTask; } function getPrintTask(n, c){ function PrintTask(){ function next(value){ console.log("result:" + value) } return getFibTask(n, next); } return PrintTask; } // Continuation:: take Continuation return Task function FinalC(c){ function FinalTask(){ return None } } var task = getPrintTask(6, FinalC); while(task){ task = task() }
-
- -
追記:まえに悩んでいた、返り値を次の関数の引数にどう渡せばいいんだろう、という話、結局関数が複数の引数を取ると考えるから複雑なので、上のadd_みたいにカリー化してしまえば1引数だから入れる場所を悩まなくてすむというおはなし。前から後ろへじゅんばんにバケツリレーしていくだけでいいわけですね。