church_encoding C++版实现

来源:互联网 发布:大众汽车销售数据采集 编辑:程序博客网 时间:2024/06/06 07:31
namespace ChurBool{//church bool To normal boolauto ToNormalBool = [](auto&&f){    return f(true, false);};auto True = [](auto&&m, auto&&){    return m;};auto False = [](auto&&, auto&&n){    return n;};auto And = [](auto&&m, auto&&n){    return m(n,m);};auto Or = [](auto&&m, auto&&n){    return m(m,n);};auto Not = [](auto&&m){    return [=](auto&&a, auto&&b)    {        return m(b,a);    };};auto Xor = [=](auto&&m, auto&&n){    return m(Not(n),n);};auto If = [](auto&&predicate){    return [=](auto&&t, auto&&f)    {        return predicate(t, f);    };};}namespace ChurNum{//church number To normal numberauto ToNormalNum = [](auto&&f){    return f([](int a)    {        return a+1;    })(0);};//0auto zero=[](auto&&){    return [](auto&&x)    {        return x;    };};//n++auto Inc=[](auto&&n){    return [=](auto&&f)    {        return [=](auto&&x)        {            return f((n(f)(x)));        };    };};//n--auto Dec = [](auto&&n){    return [=](auto&&f)    {        return [=](auto&&x)        {            return n([=](auto&&g)            {                return [=](auto&&h)                {                    return h(g(f));                };            })([=](auto&&)            {                return x;            })([](auto&&u)            {                return u;            });        };    };};//m+nauto Add=[](auto&&m, auto&&n){    return [=](auto&&f)    {        return [=](auto&&x)        {            return m(f)((n(f)(x)));        };    };};//m-nconstexpr auto Sub=[=](auto&&m, auto&&n){    return [=](auto&&f)    {        return [=](auto&&x)        {            return (n(Dec))(m)(f)(x);        };    };};//m*nauto Mul=[](auto&&m, auto&&n){    return [=](auto&&f)    {        return [=](auto&&x)        {            return m(n(f))(x);        };    };};//m^nauto Exp=[](auto&&m, auto&&n){    return [=](auto&&f)    {        return [=](auto&&x)        {            return n(m)(f)(x);        };    };};using namespace ChurBool;auto isZero = [=](auto&&n){    return n([=](auto&&)    {        return False;    })(True);};//cmp(churNum m,churNum n){return m>=n;}auto GEQ = [=](auto&&m, auto&&n){    return isZero(Sub(n,m));};auto EQU = [=](auto&&m, auto&&n){    return And(isZero(Sub(n,m)), isZero(Sub(m,n)));};auto Max = [=](auto&&m, auto&&n){    return If(GEQ(m,n))           (m,            n);};//    auto div=[=](auto&&m, auto&&n){return [=](auto&&f){return [=](auto&&x){return (n(sub))(m)(f)(x);};};};//auto div = [=](auto&&m, auto&&n)//{//    return If(GEQ(m,n))//            (//                ,)//};//auto Remainder = [=](auto&&m, auto&&n)//{//    auto ret = Sub(m,n);//    isZero(ret);//    if(ToNormalBool(GEQ(m, n)))//        return Remainder(Sub(m,n), n);//    return m;//};}using namespace ChurNum;template<size_t n>auto ToChurNum(){    return Inc(ToChurNum<n-1>());}template<>auto ToChurNum<0>(){    return zero;}namespace ChurList{    auto Cons = [](auto&&x, auto&&y)    {        return [=](auto&&z)        {            return z(x,y);        };    };    auto Car = [](auto&&p)    {        return p([](auto&&x, auto&&)        {            return x;        });    };    auto Cdr = [](auto&&p)    {        return p([](auto&&, auto&&y)        {            return y;        });    };    auto Nil = [=](auto&&)    {        return True;    };    auto isNil = [](auto&&l)    {        return l([](auto&&,auto&&)        {            return False;        });    };}int main(){    auto one = Inc(zero);    auto two = ToChurNum<2>();    auto three = Add(two, one);    auto eighteen = Mul(two, Mul(three,three));     //2*3*3    cout<<ToNormalNum(three)<<endl;                 //3    cout<<ToNormalNum(eighteen)<<endl;              //18    cout<<ToNormalNum(Exp(three,three))<<endl;      //3^3    cout<<ToNormalNum(Dec(Exp(three,three)))<<endl; //3^3-1    cout<<ToNormalNum(Sub(eighteen, three))<<endl;  //18-3    using namespace ChurBool;    cout<<boolalpha<<ToNormalBool(True)<<endl;    cout<<boolalpha<<ToNormalBool(False)<<endl;    cout<<boolalpha<<ToNormalBool(Xor(True,False))<<endl;    cout<<ToNormalNum(Max(Sub(eighteen, two), Mul(zero, two)))<<endl;    //max(18-2, 0*2)    using namespace ChurList;    auto myPair = Cons("Cons string,",Cons(1,Nil));    cout<<Car(myPair)<<Car(Cdr(myPair))<<endl;}
关于division的实现,很遗憾,这里的If并没有对两个分支的求值进行特殊处理,会出现out of memory,会无限递归下去,即SICP第一章的某一题。暂时没想到好的处理方式。求余函数同理,好遗憾啊,涉及到递归的话,那个If没法单独触发某个branch。
原创粉丝点击