-2

整数を取り、その数値を教会でエンコードされた関数の形式で返す関数が必要です。

私は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)))

(church-encode 0) を呼び出すと、教会でエンコードされたゼロのラムダが返されます。

(lambda (f x) x)

そして (church-encode 3) は次のようになります:

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

しかし、Javascriptで同じことをしたいです。できれば、ここで行ったような文字列ジャンクに頼ることなく:

(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'));
4

1 に答える 1

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)));
})();
于 2014-12-03T21:11:44.400 に答える