概述
namespace ChurBool
{
//church bool To normal bool
auto 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 number
auto ToNormalNum = [](auto&&f)
{
return f([](int a)
{
return a+1;
})(0);
};
//0
auto 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+n
auto Add=[](auto&&m, auto&&n)
{
return [=](auto&&f)
{
return [=](auto&&x)
{
return m(f)((n(f)(x)));
};
};
};
//m-n
constexpr auto Sub=[=](auto&&m, auto&&n)
{
return [=](auto&&f)
{
return [=](auto&&x)
{
return (n(Dec))(m)(f)(x);
};
};
};
//m*n
auto Mul=[](auto&&m, auto&&n)
{
return [=](auto&&f)
{
return [=](auto&&x)
{
return m(n(f))(x);
};
};
};
//m^n
auto 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。
最后
以上就是辛勤绿茶为你收集整理的church_encoding C++版实现的全部内容,希望文章能够帮你解决church_encoding C++版实现所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复