遅延評価のココロ
遅延評価ってこれであってるの?
評価しないでいいかもしれない状況なら変数(=関数)は評価しない.評価しないといけない状況になったときのみ評価する.
それは,パターンマッチ/returnを求められたとき.
つまり,評価されるのは他の関数に渡さなければならないとき.
モナドなら他の関数に引き渡すとき?
そういう風に捕らえていたんですが,あってますかね?
その後
以前に,このエントリ
で遅延評価ってできるんじゃない?と思ったんだけど,amachangさんが書いたのと似たような(amachangさんのが美しい・・・悔しい)方法(.e(),僕は.force())で解決しててちょっと嬉しい.
でも,ちょっとわからないのが,amachangさんの遅延評価は
var a = function() { return function(x) { return x; } };
してて,これだと,関数a(の処理)に値(引数)がわたるのは,評価の段階な気がします.
具体的には
a.e()(3)
とかしないと関数aには3が渡らなくて渡ったときにはすでに式は評価されるから,なんか違う気がする.
どちらかというと,
a(3)という形(?)はできてるんだけど,具体的にa(3)がいくらになるかはまだ計算されてない.
で,上に書いたように,実際に評価される時(.e())に値が決まる.
ような気がする.
amachangさんは
遅延とは引数がそのまま値を返す無引数関数で囲まれること
って書いているのですが,これが僕が馬鹿なせいかいまいちしっくり来ない.
と,思ったので
とりあえず恥ずかしげもなくこうじゃないん?と思ったのを書いてみる.
/* amachangさん作成 */ Object.prototype.force = function(){ return this.valueOf()}; Function.prototype.force = function() { return this.length != 0 ? this : this().force() }; //値を渡すけど評価は後でするfib関数 var fib = function(m){ return function(){ return (m <= 2) ? 1 : (fib(m-1).force() + fib(m-2).force()); } } //値を設定(気持ち的には別の関数に関数ごと渡している) var v = fib(10); //例えば g(fib(10)); //評価はここで v.force();
う〜ん,でもコレだと無限リストをつくって「!!」で取り出すって処理ができないのか?
もうちょっと考えます・・・