1-不支持负数
2-只能处理100以内的整数
3-只有整型和布尔值两种数据类型
4-有bug
5-支持常见的函数式编程如
i0, i1, ..., i9, i10 --- 表示数字0到10
Succ<N> --- 后继
Pred<N> --- 前驱
Add<N1, N2> --- 加
Sub<N1, N2> --- 减
Mul<N1, N2> --- 乘
Div<N1, N2> --- 除
True, False --- 布尔值
And<Bool, Bool> --- 与
Or<Bool, Bool> --- 或
Not<Bool> --- 非
Equal<N1, N2> --- 等于
LessThan<N1, N2> --- 小于
LessEqual<N1, N2> --- 小于等于
GreaterThan<N1, N2> --- 大于
GreaterEqual<N1, N2> --- 大于等于
If<Bool, Expr1, Expr2> --- 若Bool为真则值为Expr1否则为Expr2
Pair<H, T> --- 二元组
Head<Pair> --- 二元组第一个元素
Tail<Pair> --- 二元组第二个元素
List<Args...> --- 列表
Length<List> --- 列表长度
Nth<N, List> --- 列表第N个元素
Take<N, List> --- 截取列表前N个元素
Drop<N, List> --- 舍弃列表前N个元素
Concat<List1, List2> --- 链接两个列表
Map<Func, List> --- 函数式map
Filter<Func, List> --- 函数式filter
FoldLeft<Func, List> --- 函数式foldleft
Is_Integer<N> --- 辨别数字
Is_Boolean<Bool> --- 辨别布尔值
Is_Odd<N> --- 是奇数
Is_Even<N> --- 是偶数
Is_Pair<Pair> --- 是二元组
Max<N1, N2> --- 最大值
Min<N1, N2> --- 最小值
6-一些测试用函数
Assert<Bool>::True() --- 断言Bool为真
Integer<N>::ToInt --- 获得整型值
Boolean<B>::ToBool --- 获得布尔值
DisplayInteger<N>::Display() --- 显示整型值
DisplayBoolean<B>::Display() --- 显示布尔值
DisplayList<L>::Display() --- 显示列表
#pragma once
#include <iostream>
namespace raven {
/************************************************* Peano *************************************************/
// Undefined
struct Undefined {
using Pred = Undefined;
};
// Zero
struct Zero {
using Pred = Zero;
};
// Succ
template <class N>
struct Succ;
template <>
struct Succ < Zero > {
using Pred = Zero;
};
template <>
struct Succ < Undefined > {
using Pred = Undefined;
};
template <class N>
struct Succ < Succ<N> > {
using Pred = Succ<N>;
};
// Pred
template <class N>
struct Pred;
template<>
struct Pred < Zero > {
using Value = Zero;
};
template<>
struct Pred < Undefined > {
using Value = Undefined;
};
template<class N>
struct Pred < Succ<N> > {
using Value = N;
};
/************************************************* Boolean Logic *************************************************/
// True False
struct True {
const static bool ToBool = true;
};
struct False {
const static bool ToBool = false;
};
// And
template <class B1, class B2>
struct And {
using Value = False;
};
template <>
struct And < True, True > {
using Value = True;
};
// Or
template <class B1, class B2>
struct Or {
using Value = True;
};
template <>
struct Or < False, False > {
using Value = False;
};
// Not
template <class B>
struct Not {
using Value = False;
};
template <>
struct Not < False > {
using Value = True;
};
/************************************************* Operator *************************************************/
// Equal
template <class T1, class T2>
struct Equal {
using Value = False;
};
template <class T>
struct Equal < T, T > {
using Value = True;
};
// Less Than
template <class N1, class N2>
struct LessThan {
using Value = typename LessThan<typename N1::Pred, typename N2::Pred>::Value;
};
template <class N>
struct LessThan < Zero, N > {
using Value = True;
};
template <class N>
struct LessThan < N, Zero > {
using Value = False;
};
template <>
struct LessThan < Zero, Zero > {
using Value = False;
};
// Less Equal
template <class N1, class N2>
struct LessEqual {
using Value = typename Or<typename Equal<N1, N2>::Value, typename LessThan<N1, N2>::Value>::Value;
};
// Greater Than
template <class N1, class N2>
struct GreaterThan {
using Value = typename GreaterThan<typename N1::Pred, typename N2::Pred>::Value;
};
template <class N>
struct GreaterThan < Zero, N > {
using Value = False;
};
template <class N>
struct GreaterThan < N, Zero > {
using Value = True;
};
template <>
struct GreaterThan < Zero, Zero > {
using Value = False;
};
// Greater Equal
template <class N1, class N2>
struct GreaterEqual {
using Value = typename Or<typename Equal<N1, N2>::Value, typename GreaterThan<N1, N2>::Value>::Value;
};
/************************************************* Statement *************************************************/
// If
template <class B, class S1, class S2>
struct If;
template <class S1, class S2>
struct If < True, S1, S2 > {
using Value = S1;
};
template <class S1, class S2>
struct If < False, S1, S2 > {
using Value = S2;
};
/************************************************* Calculate *************************************************/
// Add
template <class N1, class N2>
struct Add;
template <class N>
struct Add < Zero, N > {
using Value = N;
};
template <class N1, class N2>
struct Add < Succ<N1>, N2 > {
using Value = typename Add<N1, Succ<N2>>::Value;
};
// Mul
template <class N1, class N2>
struct Mul;
template <class N>
struct Mul < Zero, N > {
using Value = Zero;
};
template <class N1, class N2>
struct Mul < Succ<N1>, N2 > {
using Value = typename Add<N2, typename Mul<N1, N2>::Value>::Value;
};
// Sub
template <class N1, class N2>
struct Sub {
using Value = typename Sub<typename N1::Pred, typename N2::Pred>::Value;
};
template <class N>
struct Sub < N, Zero > {
using Value = N;
};
template <class N>
struct Sub < Zero, N > {
using Value = Zero;
};
template <>
struct Sub < Zero, Zero > {
using Value = Zero;
};
// Div
template <class N1, class N2>
struct Div {
using Value = typename If<typename GreaterEqual<N1, N2>::Value, Succ<typename Div<typename Sub<N1, N2>::Value, N2>::Value>, Zero>::Value;
using Rem = typename If<typename GreaterEqual<N1, N2>::Value, typename Div<typename Sub<N1, N2>::Value, N2>::Rem, N1>::Value;
};
template <class N>
struct Div < Zero, N > {
using Value = Zero;
using Rem = Zero;
};
template <class N>
struct Div < N, Zero > {
using Value = Undefined;
using Rem = Undefined;
};
// Number
using i0 = Zero;
using i1 = Succ < Zero > ;
using i2 = Succ < i1 > ;
using i3 = Succ < i2 > ;
using i4 = Succ < i3 > ;
using i5 = Succ < i4 > ;
using i6 = Succ < i5 >;
using i7 = Succ < i6 >;
using i8 = Succ < i7 >;
using i9 = Succ < i8 >;
using i10 = Succ < i9 >;
// Decimal
/* template <class N, class D, class...R> struct Decimal_X { using Value = typename Decimal_X<typename Add<typename Mul<i10, N>::Value, D>::Value, R...>::Value; }; template <class N, class D> struct Decimal_X < N, D > { using Value = typename Add<typename Mul<i10, N>::Value, D>::Value; }; template <class D, class... R> struct Decimal { using Value = typename Decimal_X<Zero, D, R...>::Value; }; */
/************************************************* Data Struct *************************************************/
// Pair
struct Nil {
using Length = Zero;
};
template<class First, class Rest>
struct Pair {
using Head = First;
using Tail = Rest;
using Length = Succ < typename Rest::Length > ;
};
// Pair Head
template <class Pair>
struct Head;
template <class H, class T>
struct Head < Pair<H, T> > {
using Value = H;
};
// Pair Tail
template <class Pair>
struct Tail;
template <class H, class T>
struct Tail < Pair<H, T> > {
using Value = T;
};
// List
template <class Head, class... Tail>
struct List {
using Value = Pair < Head, typename List<Tail...>::Value > ;
using Length = typename Value::Length;
};
template<class Head>
struct List < Head > {
using Value = Pair < Head, Nil > ;
using Length = i1;
};
// ListToDecimal
template <class N, class List>
struct ListToDecimal_X;
template <class N, class H, class T>
struct ListToDecimal_X < N, Pair<H, T> > {
using Value = typename ListToDecimal_X<typename Add<typename Mul<i10, N>::Value, H>::Value, T>::Value;
};
template <class N>
struct ListToDecimal_X < N, Nil > {
using Value = N;
};
template <class List>
struct ListToDecimal {
using Value = typename ListToDecimal_X<i0, List>::Value;
};
/************************************************* Algorithm *************************************************/
// List Length
template <class List>
struct Length;
template <class H, class T>
struct Length < Pair<H, T> > {
using Value = Succ < typename Length<T>::Value > ;
};
template <>
struct Length < Nil > {
using Value = Zero;
};
// List Take
template <class N, class List>
struct Take {
using Value = Pair < typename List::Head, typename Take<typename N::Pred, typename List::Tail>::Value > ;
using Length = typename Value::Length;
};
template <class N>
struct Take < N, Nil > {
using Value = Nil;
using Length = Zero;
};
template <class List>
struct Take < Zero, List > {
using Value = Nil;
using Length = Zero;
};
// List Nth
template <class N, class List>
struct Nth;
template <class H, class T, class N>
struct Nth < Succ<N>, Pair<H, T> > {
using Value = typename Nth<N, T>::Value;
};
template <class N>
struct Nth < N,Nil > {
using Value = Nil;
};
template <class H, class T>
struct Nth < Zero, Pair<H, T> > {
using Value = H;
};
// List Drop
template <class N, class List>
struct Drop;
template <class N, class H, class T>
struct Drop < Succ<N>, Pair<H, T> > {
using Value = typename Drop<N, T>::Value;
};
template <class List>
struct Drop < Zero, List > {
using Value = List;
};
template <class N>
struct Drop < N, Nil > {
using Value = Nil;
};
// List Concat
template <class L1, class L2>
struct Concat;
template <class H, class T, class List>
struct Concat < Pair<H, T>, List > {
using Value = Pair < H, typename Concat<T, List>::Value > ;
};
template <class List>
struct Concat < Nil, List > {
using Value = List;
};
/************************************************* Lambda *************************************************/
template <template <class A> class F, class L>
struct Map;
template <template <class A> class F, class H, class T>
struct Map < F, Pair<H, T> > {
using Value = Pair < typename F<H>::Value, typename Map<F, T>::Value > ;
};
template <template<class A> class F>
struct Map < F, Nil > {
using Value = Nil;
};
template <template <class A, class B> class F, class I, class L>
struct FoldLeft {
using Value = typename FoldLeft<F, typename F<I, typename L::Head>::Value, typename L::Tail>::Value;
};
template <template <class A, class B> class F, class I>
struct FoldLeft < F, I, Nil > {
using Value = I;
};
template <template <class A> class F, class L>
struct Filter {
using Value = typename If<typename F<typename L::Head>::Value,
Pair<typename L::Head, typename Filter<F, typename L::Tail>::Value>,
typename Filter<F, typename L::Tail>::Value>::Value;
};
template <template <class A> class F>
struct Filter < F, Nil > {
using Value = Nil;
};
/************************************************* Function *************************************************/
// Max
template <class N1, class N2>
struct Max {
using Value = typename If<typename GreaterThan<N1, N2>::Value, N1, N2>::Value;
};
// Min
template <class N1, class N2>
struct Min {
using Value = typename If<typename LessThan<N1, N2>::Value, N1, N2>::Value;
};
// Is_Odd
template <class N>
struct Is_Odd {
using Value = typename Equal<typename Div<N, i2>::Rem, i1>::Value;
};
// Is_Even
template <class N>
struct Is_Even {
using Value = typename Equal<typename Div<N, i2>::Rem, i0>::Value;
};
// Is_Integer
template <class N>
struct Is_Integer {
using Value = False;
};
template <class N>
struct Is_Integer < Succ<N> > {
using Value = True;
};
template <>
struct Is_Integer < Zero > {
using Value = True;
};
// Is_Boolean
template <class B>
struct Is_Boolean {
using Value = False;
};
template <>
struct Is_Boolean < True > {
using Value = True;
};
template <>
struct Is_Boolean < False > {
using Value = True;
};
// Is_Nil
template <class X>
struct Is_Nil {
using Value = False;
};
template <>
struct Is_Nil < Nil > {
using Value = True;
};
// Is_Pair
template <class P>
struct Is_Pair {
using Value = False;
};
template <class X, class Y>
struct Is_Pair < Pair<X, Y> > {
using Value = True;
};
/************************************************* Test Tool *************************************************/
// Assert
template <class E>
struct Assert {
inline static void True() { throw 0; }
};
template <>
struct Assert < True > {
inline static void True() {}
};
// Integer
template <class N>
struct Integer {
const static int ToInt = -65536;
};
template <>
struct Integer < Zero > {
const static int ToInt = 0;
};
template <class N>
struct Integer < Succ<N> > {
const static int ToInt = Integer<N>::ToInt + 1;
};
// Boolean
template <class B>
struct Boolean {
const static bool ToBool = false;
};
template <>
struct Boolean < True > {
const static bool ToBool = true;
};
template <>
struct Boolean < False > {
const static bool ToBool = false;
};
// Display Integer
template <class N>
struct DisplayInteger {
inline static void Display() {
std::cout << Integer<N>::ToInt << std::endl;
}
};
// Display Boolean
template <class B>
struct DisplayBoolean {
inline static void Display() {
if (Boolean<B>::ToBool) std::cout << "true" << std::endl;
else std::cout << "false" << std::endl;
}
};
// Display List
template <class P>
struct DisplayList;
template <class H, class T>
struct DisplayList < Pair<H, T> > {
inline static void Display() {
if (Is_Integer<H>::Value::ToBool) {
std::cout << Integer<H>::ToInt << " ";
}
else if (Is_Boolean<H>::Value::ToBool) {
if (Boolean<H>::ToBool) std::cout << "true ";
else std::cout << "false ";
}
DisplayList<T>::Display();
}
};
template <>
struct DisplayList < Nil > {
inline static void Display() {
std::cout << std::endl;
}
};
}
cout << "[Pred 2] " << Integer<i2::Pred>::ToInt << endl;
cout << "[Pred 3] " << Integer<Pred<i3>::Value>::ToInt << endl;
cout << "[And True False] " << Boolean<And<True, False>::Value>::ToBool << endl;
cout << "[Or False False] " << Boolean<Or<False, False>::Value>::ToBool << endl;
cout << "[If True 1+2 3+4] " << Integer<If<True, Add<i1, i2>::Value, Add<i3, i4>::Value>::Value>::ToInt << endl;
cout << "[LessThan 1 2] " << Boolean<LessThan<i1, i2>::Value>::ToBool << endl;
cout << "[GreaterThan 2 1] " << Boolean<GreaterThan<i2, i1>::Value>::ToBool << endl;
cout << "[If (LessThan 1 2) 1 2] " << Integer<If<LessThan<i1, i2>::Value, i1, i2>::Value>::ToInt << endl;
cout << endl;
cout << "[Length (List 1 2 3 4 5)] " << Integer<Length<List<i1, i2, i3, i4, i5>::Value>::Value>::ToInt << endl;
cout << "[Head (Pair 3 6)] " << Integer<Head<Pair<i3, i6>>::Value>::ToInt << endl;
cout << "[Tail (Pair 3 6)] " << Integer<Tail<Pair<i3, i6>>::Value>::ToInt << endl;
cout << "[Head (List 1 2 3 4 5)] " << Integer<Head<List<i1, i2, i3, i4, i5>::Value>::Value>::ToInt << endl;
cout << endl;
cout << "[take 1 (list 1 2 3 4 5)] " << Integer<Take<i1, List<i1, i2, i3, i4, i5>::Value>::Value::Length>::ToInt << endl;
cout << "[Nth 3 (List 1 2 3 4 5)] " << Integer<Nth<i3, List<i1, i2, i3, i4, i5>::Value>::Value>::ToInt << endl;
cout << "[Head (Drop 2 (List 1 2 3 4 5))] " << Integer<Head<Drop<i2, List<i1, i2, i3, i4, i5>::Value>::Value>::Value>::ToInt << endl;
cout << "[Nth 2 (Concat (List 1 2) (List 3 4)] " << Integer<Nth<i2, Concat<List<i1, i2>::Value, List<i3, i4>::Value>::Value>::Value>::ToInt << endl;
cout << "[Nth 2 (Map F (List 1 2 3))] " << Integer<Nth<i2, Map<F, List<i1, i2, i3>::Value>::Value>::Value>::ToInt << endl;
cout << endl;
cout << "[LessThan 1 3] " << Boolean<LessThan<i1, i3>::Value>::ToBool << endl;
cout << "[LessEqual 2 2] " << Boolean<LessEqual<i2, i2>::Value>::ToBool << endl;
cout << "[GreaterThan 1 3] " << Boolean<GreaterThan<i1, i3>::Value>::ToBool << endl;
cout << "[GreaterEqual 3 1] " << Boolean<GreaterEqual<i3, i1>::Value>::ToBool << endl;
cout << "[GreaterEqual 1 2] " << Boolean<GreaterEqual<i1, i2>::Value>::ToBool << endl;
cout << "[GreaterThan 1 2] " << Boolean<GreaterThan<i1, i2>::Value>::ToBool << endl;
cout << "[Equal 1 2] " << Boolean<Equal<i1, i2>::Value>::ToBool << endl;
cout << "[greaterEqual 1 2] " << Boolean<GreaterEqual<i1, i2>::Value>::ToBool << endl;
cout << "[Or (GreatThan 1 2) (Equal 1 2)] " << Boolean<Or<GreaterThan<i1, i2>::Value, Equal<i1, i2>::Value>::Value>::ToBool << endl;
cout << endl;
cout << "[Add 4 7] " << Integer<Add<i4, i7>::Value>::ToInt << endl;
cout << "[Sub 4 7] " << Integer<Sub<i4, i7>::Value>::ToInt << endl;
cout << "[Sub 7 4] " << Integer<Sub<i7, i4>::Value>::ToInt << endl;
cout << "[Div 8 3] " << Integer<Div<i8, i3>::Value>::ToInt << endl;
cout << endl;
cout << "[FoldLeft Add 0 (list 1 2 3 4 5)] " << Integer<FoldLeft<Add, i0, List<i1, i2, i3, i4, i5>::Value>::Value>::ToInt << endl;
cout << "[Length (Filter Is_Odd (List 1 2 3 4 5))] " << Integer<Length<Filter<Is_Odd, List<i1, i2, i3, i4, i5>::Value>::Value>::Value>::ToInt << endl;
DisplayList<List<i1, True, i3, i4, i5>::Value>::Display();
cout << endl;
DisplayInteger<ListToDecimal<List<i2, i2, i3>::Value>::Value>::Display();