関数で数(四)数の完全な消失を表す方法


前のは前菜だけで、前のコードの例がわかるようにしてからこれを見てみましょう.これはあなたが閉鎖がどういうことなのかを完全に理解していることを示しています.
前の例では、最終的には開始数を表す数が必要です.では、まだ私たちの目的を完全に達成していません.しかし、もし完全に関数で数の代わりに使うならば、私たちはどのように1つの関数が確かにその数を表すことを証明しますか?
そのためには、まず数が何なのかを考察する必要があります.
最も原始的な表示数の方法を考えてみましょう:指で数えて、10本の指が数え終わったら、数えて終わります.もしあなたが羊飼いであれば、10頭以上の羊がいて、10より大きい数を表すことができます.しかし、人間が5本の指と5本の羊のつながりが何なのかを理解したいとき、彼らは5本の羊や5本の指で5を表す必要はありません.数字5の記号を言えばいいので、人間は抽象的な概念抽出の過程を完成しました.
したがって、最も原始的な数の概念:1つの数は1つの物事の繰り返しの回数を表す.
完全に関数だけで、数のない世界で、どのようにカウントするか想像してみてください.方法は、この関数に対して1つの関数を入力して実行し(注意して、数えていません)、この関数の内容はN回実行されて、この関数を実行する関数がNという数を代表していることを表します.
したがって、0を表す関数があると仮定します.
zero = f(x)
プラス1を表す関数もあります
incr = f(x)
では1は
one = incr(zero)
2は
two = incr(incr(zero))
より多くの数は
three=incr(incr(incr(zero))four=incr(incr(incr(incr(zero))five=incr(incr(incr(incr(incr(zero))・・自然数NはincrのN次方(zero)として表すことができる
だから、まずzeroとincrを表す関数を定義して、他のすべての数を表すことができます.
次に、これはzeroの表示です
function zero(f){
	return function(x){
		return x;
	}
}

この関数は、1つの関数fを入力すると、zeroはあなたに1つの関数を返し、zeroで返された関数で、もう1つのxを入力します.このとき、zeroが返された関数はこのxをそのまま返します.この関数は役に立たないように見えますが、前に数を表す関数の定義に合っていて、fを入力しても、一度も実行されません.ではxはここで何をしているのでしょうか.
x自体には何の意味もありません.それは占有に使われているだけです.数が存在する境界を表します.これはC言語の文字列配列の'0'に似ています.どの文字列配列にも表示されませんが、どの文字列配列にも離れられません.
注意:次にn(f)(x)のような形をした式がたくさん見られますが、皆さんが見ている間に気絶しないように、ここで重点的に強調して、nが関数の数を表すものであれば、n(f)(x)の意味はf(x)をn回転用することです.
repeat(n,f,x)の関数で同じことができると思っているかもしれませんが、まず、nは数字ではなく、nはいくつかの抽象について注意する必要があります.また、この設計はrepeatよりも抽象的で、柔軟で、強力な関数を得ることができます.後で悟ってほしいです.
この例では,f,x,fを2つの印刷アヒルの関数で表し,1を増やし,xを緑色のアヒルを印刷し,0を表す.
function yellowduck(x){
  print('<img src="http://thumbs.dreamstime.com/thumbimg_426/1249659187Yb2Igm.jpg">');
}
function greenduck(x){
 print('<img src="http://www.greenduck.co.uk/images/about/logo.gif">');
}

2つの方法のパラメータは、ここでの例では何の役にも立たないことに注意してください.なぜなら、入力されたxが何であるかにかかわらず、アヒルは1匹しか印刷されないからです.
気まずいことに、入力された緑のアヒルを印刷する方法は呼び出されません.例えば、文字列の配列ごとに0を追加しましたが、0は表示されませんでした.そのため、印刷数を表示する方法を書く必要があります.人為的に原数を印刷した後、緑のアヒルを印刷して終わりを表します.printduckは私たちが1つの数を簡単に見るためだけです.
function printduck(n){
	n(yellowduck)(greenduck);//greenduck never be called at this line;
	greenduck(null);//execute it manually;
}

関数が実行されているのを見ると、緑のアヒルが0で印刷され、黄色のアヒルの後ろに緑のアヒルが1であることが印刷されます.
これは0を印刷するコードです.
 <!DOCTYPE html>
<html>
<body>
<script language="javascript" type="text/javascript">
<!--
function print(){
  var vars = print.arguments;
  var arr = [];
  for (var i = 0; i < vars.length; i++){  
        arr.push(vars[i]);  
  }  
  document.write(arr.join(',')+'<br/>');
}


function yellowduck(x){
  print('<img src="http://thumbs.dreamstime.com/thumbimg_426/1249659187Yb2Igm.jpg">');
}
function greenduck(x){
 print('<img src="http://www.greenduck.co.uk/images/about/logo.gif">');
}


function zero(f){
  return function(x){
    return x;
  }
}


function printduck(n){
 n(yellowduck)(greenduck);//greenduck never be called at this line;
 greenduck(null);//execute it manually;
} 

次に増1がどのように定義されているかを見てみましょう
function incr(n){
  return function(f){
    return function(x){
      return f(n(f)(x));  
    }
  }
}
見て
ちょっとめまいがしますか?焦らないで、中の関数を分解してみましょう.1行を2行に分解すれば分かります.
function incr(n){
  return function(f){
    return function(x){
      executed = n(f)(x);
      return f(executed);  
    }
  }
}

前述したように、n(f)(x)の式のように、f(x)をnパス実行することを表す.したがって,この関数はnパスを実行した後にf(x)をもう一度呼び出すことであり,1回増やしたのではないか.
私たちがincr(zero)(yellowduck)(greenduck)を実行するときを考えてみましょう.私たちが得たのは
yellowduck(zero(yellowduck)(greenduck));
前に分析したように、zero(f)(x)は何も実行しません.したがって,式の結果はyellowduckが1回実行される.
だから
one = incr(zero);
また見てみましょう
Incr(one)(yellowduck)(greenduck)の場合、
yellowduck(one(yellowduck)(greenduck));
one(yellowduck)はyellowduck(zero(yellowduck)に等しい.上式に持ち込む
yellowduck(yellowduck(zero(yellowduck)(greenduck)));
この過程をずっと続けていくと、私たちは
n = yellowduck(yellowduck........(yellowduck(zero(yellowduck)(greenduck)));
n回yellowduck(x)が呼び出されたのと等しく,我々の以前の定義と完全に一致している.
実際の状況を見てみましょう
var one = incr(zero);
var two = incr(one);
var three = incr(two);

printduck(one);
printduck(two);
printduck(three);
不思議なことが起こりました!私たちの例には確かに数の存在はありませんが、私たちは確かに関数からなる関数を使って、数の概念を表現しました!
(続き)