2014-12-03 20 views
-2

我想要一個函數,它接受一個整數並以church encoded函數的形式返回該數字。在Javascript中爲任意整數生成教會編碼數字

我在newlisp實現這一點:

(define (reduce stencil sq) (apply stencil sq 2)) 
(define (num n) (cond 
    ((= n 0) 'x) 
    ((< n 2) '(f x)) 
    (true (reduce (fn (l i) (list 'f l)) (cons '(f x) (sequence 2 n)))))) 
(define (church-encode n) 
    (letex ((body (num n))) 
    (fn (f x) body))) 

如果我叫(教堂編碼0)我回來的教堂編碼零拉姆達:

(lambda (f x) x) 

和(church-編碼3)將產生:

(lambda (f x) (f (f (f x)))) 

但我想在JavaScript中做同樣的事情。最好不採取串JANK像我這樣做這裏:

(function (_) { 
    var asnum = function(x) { return x((function(x) {return x+1;}), 0); }; 
    function church_encode(n) { 
     function genBody() { 
      return _.reduce(_.range(n), function(e,x) { 
       return e.replace("x", "f(x)"); 
      }, "x"); 
     } 
     eval("var crap = function (f, x) { return "+genBody()+"; }"); 
     return crap; 
    } 
    var encoded_nums = _.map(_.range(11), church_encode); 
    var numerics = _.map(encoded_nums, asnum); 
    console.log(numerics); 
})(require('lodash')); 
+0

如果包含在問題*與它是如何工作的簡要說明你的newlisp代碼*這將是很好。 – 2014-12-03 18:50:28

+0

你的問題是什麼?你的JavaScript版本的代碼有什麼問題? – Bergi 2014-12-03 18:57:46

+0

@Bergi真的嗎? 「最好不要訴諸字符串jank。」很明顯,javascript支持的可怕性很差,並且必須有更好的方法來實現它,而不是採用eval。畢竟這是lambda微積分,所以這都是手淫。 :P – Squirrelsama 2014-12-03 21:33:22

回答

1
(function() { 
    function range(n){ 
     var l = []; 
     for(var i = 0; i < n; i++){ 
      l.push(i); 
     } 
     return l; 
    } 
    function church_encode(n) { 
     if(n < 1) 
      return function(f, x) { return x; }; 
     if(n === 1) 
      return function(f, x) { return f(x); }; 

     function succ (n) { 
      return function(f,x) { 
       return n(f,f(x)); 
      } 
     } 
     return range(n).reduce(function(a){ 
      return succ(a); 
     }, function (f,x) { return x; }); 
    } 
    function to_int(f){ 
     var i = 0; 
     f(function(){ i++ }); 
     return i; 
    }; 
    console.log(to_int(church_encode(5))); 
})();