2010/10/08

JavaScript の継続(continuation)によるループ

ちょっと試してみました。JavaScript の処理系は Rhino(Rhino 1.7 release 2 2009 03 22) です。

Continuation を使って sum を定義してみました。
function callcc (f){
  return f(new Continuation());
}

function identity (x){
  return x;
}

function sum (n){
  var i = 0;
  var total  = 0;
  var hop = new Continuation();
  var next = callcc(identity);

  if (n < i){
    hop(total);
  } else {
    total += i;
    ++i;
    next(next);
  }
}

sum(10);
// -> 55

loop 関数にしてみました。loop 関数を使って sum と fact を定義してみました。期待通りに動いているようです。
function loop (func){
  var hop = new Continuation();
  var next = callcc(identity);
  func(hop);
  next(next);
}

function fact (i) {
  var acc = 1;
  return loop (function (hop){
                 if (i === 0){
                   hop(acc);
                 } else {
                   acc *= i--;
                 }
               });
}

fact(10);
// 3628800

function sum (i) {
  var acc = 0;
  return loop (function (hop) {
                 if (i === 0){
                   hop(acc);
                 } else {
                   acc += i--;
                 }
               });
}

sum(10);
// 55

accum を定義。
function accum (i, pred, afunc, ifunc, seed){
  var acc = seed;
  return loop (function (hop){
                 if (pred(i)) {
                   hop(acc);
                 } else {
                   acc = afunc(i, acc);
                   i = ifunc(i);
                 }});
}

function zerop (i){
  return i === 0;
}

function dec (i){
  return --i;
}

function mul (x, y){
  return x * y;
}

function plus (x, y){
  return x + y;
}

function sum (i){
  return accum (i, zerop, plus, dec, 0);
}

function fact (i){
  return accum(i, zerop, mul, dec, 1);
}

sum(10);
// -> 55
fact(10);
// -> 3628800


while を使えば良い話なんですけどね。

JavaScript 第5版

0 件のコメント:

コメントを投稿