0%

邱奇编码的javascript实现

📃正文

加减乘

廖雪峰老师的网站看到了闭包内容,其中的脑洞大开部分就是关于邱奇编码的加法。

加法

'use strict';

// 定义数字0:
var zero = function (f) {
  return function (x) {
    return x;
  }
};

// 定义数字1:
var one = function (f) {
  return function (x) {
    return f(x);
  }
};

// 定义加法:
function add(n, m) {
  return function (f) {
    return function (x) {
      return m(f)(n(f)(x));
    }
  }
}
// 计算数字2 = 1 + 1:
var two = add(one, one);

// 计算数字3 = 1 + 2:
var three = add(one, two);

// 计算数字5 = 2 + 3:
var five = add(two, three);

// 你说它是3就是3,你说它是5就是5,你怎么证明?

// 呵呵,看这里:

// 给3传一个函数,会打印3次:
(three(function () {
  console.log('print 3 times');
}))();

// 给5传一个函数,会打印5次:
(five(function () {
  console.log('print 5 times');
}))();

// 继续接着玩一会...

加法其实比较好理解,关于减法部分在网上搜索了很久。找到的代码比较难理解。

减法

var ZERO = function (f){
  return function (z){
    return z;
  }
};

var ADD1 = function (n){
  return function (f){
    return function (z){
      return f(n(f)(z));
    }
  }
};

var pred = function(n){
  return function(action){
    return function(x){
      var fx = function(g){
        return function(h){
          return h(g(action));
        };
      };
      return n(fx)(function(u){
        return x;
      })(function(u){
        return u;
      });
    };
  };
};
var TWO = pred(THREE)=function(action){
  return function(x){
    return THREE(function(g){
      return function(h){
        return h(g(action));
      };
    };)(function(u){
      return x;
    })(function(u){
      return u;
    });
  };
};
TWO(action)(x)=function(x){
  return THREE(function(g){
    return function(h){
      return h(g(action));
    };
  };)(function(u){
    return x;
  })(function(u){
    return u;
  });
}(x)=THREE(function(g){
  return function(h){
    return h(g(action));
  };
})(function(u){
  return x;
})(function(u){
  return u;
})
var SUB1 = function (n){
  return function (f){
    return function(z){
      return ((n (function(g){
        return (function(h){
          return h(g(f));
        })
      })){
        return (function(u){
          return z;
        }))(function (u){
          return u;
        })
      }
    }
  }
};
var ONE = ADD1(ZERO);
var TWO = ADD1(ONE);
var THREE = ADD1(TWO);
(TWO(function(){
  console.log('1');
}))();
(THREE(function(){
  alert('2');
}))();
THREE = function(f){
  return function(x){
    return f(f(ONE(f)(x)));
  };
};
THREE(f) = function(x){
  return f(f(ONE(f)(x)));
};
TWO = pred(THREE) = function(action){
  return function(x){
    return THREE(function(g){
      return function(h){
        return h(g(action));
      };
    })(function(u){
      return x;
    })(function(u){
      return u;
    });
  };
}
TWO(action) = function(x){
  return THREE(function(g){
    return function(h){
      return h(g(action));
    };
  })(function(u){
    return x;
  })(function(u){
    return u;
  });
}
TWO(action)(x) = THREE(function(g){
  return function(h){
    return h(g(action));
  };
})(function(u){
  return x;
})(function(u){
  return u;
})
/*function(g){
  return function(h){
    return h(g(action));
  };
}=f
f(x)=function(g){
  return function(h){
    return h(g(action));
  };
}(x)=function(h){
  return h(x(action));
}
function(h){
  return h(x(action));
}(x)=x(x(action))
f(f(ONE(f)(x)))(g)
f(f(f(x)))(g)
f(f(x))(g)
*/
TWO(action)(x) = function(x){
  return f(f(ONE(f)(x)));
}(function(u){
  return x;
})(function(u){
  return u;
})
= f(f(ONE(f)(function(u){
  return x;
})))(function(u){
  return u;
})
= f(f(f(function(u){
  return x;
})))(function (u){
  return u;
})
=f(f(function(h){
  return h(function(u){
    return x;
  }(action));
}))(function (u){
  return u;
})
=f(function(h){
  return h(function(h){
    return h(function(u){
      return x;
    }(action));
  }(action));
})(function (u){
  return u;
})
= function(h){
  return h(function(h){
    return h(function(h){
      return h(function(u){
        return x;
      }(action));
    }(action));
  }(action));
}(function (u){
  return u;
})
= function(u){
  return u;
}(function(h){
    return h(function(h){
      return h(function(u){
        return x;
      }(action));
    }(action));
  }(action))
= function(h){
    return h(function(h){
      return h(function(u){
        return x;
      }(action));
    }(action));
  }(action)
= action(function(h){
      return h(function(u){
        return x;
      }(action));
    }(action))
= action(action(function(u){
        return x;
      }(action)))
= action(action(x));
TWO = function(f){
  return function(x){
    return f(ONE(f)(x));
  }
}
ONE(f)(x)=f(ZERO(f)(x))=f(x);
ONE = function(f){
  return function(x){
    return f(ZERO(f)(x));
  }
}

其实到最后算出结果我也没绕出弯来🙃

乘法

function multi(n, m) {  
  return function (f) {
    return function (x) {
      return m(n(f))(x);
    }
  }
}
//test six
var  six = multi(three,two);
(multi(function () {
  console.log('print 6 times');
}))();

大佬们果然都很喜欢挑战自己(lll¬ω¬)。