2017-05-07 3 views
0

以下のトランポリンコードでは、マイボタンから onclick = export(add,5)を私のビューに表示します。この呼び出しが、5の値を返さないようにするにはどうすればよいですか?下のコードで//x=0の行をコメント解除しないでください。輸出機能を純粋な機能として設定する必要があります

var x = 0; 

function repeat(operation, num) { 
    return function() { 
     if (num <= 0) { 
      console.log(x); 
      // x=0; 
      return; 
     } 
     operation(); 
     return repeat(operation, --num); 
    } 
} 

function trampoline(fn) { 
    while (fn && typeof fn === 'function') { 
     fn= fn(); 
    } 
} 

this.export = function (operation, num) { 
    trampoline(function() { 
     return repeat(operation, num); 
    }); 
} 

function add() 
{ 
    ++x; 
} 

基本的に、私は私の変数xの範囲は、プログラムは常に他の言葉で(n回を実行し、同じ出力を返すようになります解決策を望んでいた、私は純粋として「輸出」を設定したいです関数)

答えて

1

あなたが求めていることはわかりませんが、この関数の外部状態、突然変異、または再割り当てに依存する理由はありません。 ++x--nは、機能プログラミングの幻想的な土地での悪夢です。あなたはそれらをほとんど共通のパターンで避けたいでしょう。

// checking typeof === 'function' is not really reliable in functional programming 
 
// function return values are perfectly good return types 
 
// use data abstraction to mark tail calls 
 
const trampoline = { 
 
    bounce: (f, x) =>({ isBounce: true, f, x}), 
 
    run: t => { 
 
    while (t && t.isBounce) 
 
     t = t.f(t.x) 
 
    return t 
 
    } 
 
} 
 

 
// local binding, no mutation, just return x + 1 
 
const add = x => x + 1 
 

 
// bounced repeat 
 
const repeatAux = (f,n) => x => 
 
    n === 0 ? x : trampoline.bounce(repeatAux(f, n - 1), f(x)) 
 

 
// this is the function you export 
 
// it runs trampolined repeatAux with initial state of 0 
 
const repeat = (f,n) => 
 
    trampoline.run(repeatAux(f,n)(0)) 
 

 
// all calls to repeat are pure and do not require external state, mutation, or reassignment 
 
console.log(repeat(add, 5)) // 5 
 
console.log(repeat(add, 5)) // 5 
 
console.log(repeat(add, 7)) // 7 
 
console.log(repeat(add, 7)) // 7 
 

 
// repeat 1 million times to show trampoline works 
 
console.log(repeat(add, 1e6)) // 1000000


ES5、要求されたとして

var trampoline = { 
 
    bounce: function (f, x) { 
 
    return ({ isBounce: true, f, x}) 
 
    }, 
 
    run: function (t) { 
 
    while (t && t.isBounce) 
 
     t = t.f(t.x) 
 
    return t 
 
    } 
 
} 
 

 
var add = function (x) { return x + 1 } 
 

 
var repeatAux = function (f,n) { 
 
    return function (x) { 
 
    return n === 0 
 
     ? x 
 
     : trampoline.bounce(repeatAux(f, n - 1), f(x)) 
 
    } 
 
} 
 

 
var repeat = function (f,n) { 
 
    return trampoline.run(repeatAux(f,n)(0)) 
 
} 
 

 
console.log(repeat(add, 5)) // 5 
 
console.log(repeat(add, 5)) // 5 
 
console.log(repeat(add, 7)) // 7 
 
console.log(repeat(add, 7)) // 7 
 
console.log(repeat(add, 1e6)) // 1000000

+0

おかげNaomik。それは私の質問に完全に答えます。私は明示的にxをクリアすることなく、この関数を純粋にするために探していました。しかし、あなたは同等のECMAScript 5を持っていますか?それは大きな助けになるでしょう。 – vamsee

+0

@vamsee、私はes5を追加 – naomik

+0

ありがとうNaomik。私は真剣です :) – vamsee

関連する問題