1-不支持负数
2-只能处理100以内的整数
3-只有整型和布尔值两种数据类型
4-有bug
5-支持常见的函数式编程如
i0, i1, ..., i9, i10 --- 表示数字0到10
Succ --- 后继
Pred --- 前驱
Add --- 加
Sub --- 减
Mul --- 乘
Div --- 除
True, False --- 布尔值
And --- 与
Or --- 或
Not --- 非
Equal --- 等于
LessThan --- 小于
LessEqual --- 小于等于
GreaterThan --- 大于
GreaterEqual --- 大于等于
If --- 若Bool为真则值为Expr1否则为Expr2
Pair --- 二元组
Head --- 二元组第一个元素
Tail --- 二元组第二个元素
List --- 列表
Length --- 列表长度
Nth --- 列表第N个元素
Take --- 截取列表前N个元素
Drop --- 舍弃列表前N个元素
Concat --- 链接两个列表
Map --- 函数式map
Filter --- 函数式filter
FoldLeft --- 函数式foldleft
Is_Integer --- 辨别数字
Is_Boolean --- 辨别布尔值
Is_Odd --- 是奇数
Is_Even --- 是偶数
Is_Pair --- 是二元组
Max --- 最大值
Min --- 最小值
6-一些测试用函数
Assert::True() --- 断言Bool为真
Integer::ToInt --- 获得整型值
Boolean::ToBool --- 获得布尔值
DisplayInteger::Display() --- 显示整型值
DisplayBoolean::Display() --- 显示布尔值
DisplayList::Display() --- 显示列表
#pragma once
#include
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 > {
using Pred = Succ;
};
// 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 > {
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::Value, typename LessThan::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::Value, typename GreaterThan::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, N2 > {
using Value = typename Add>::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, N2 > {
using Value = typename Addtypename Mul::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::Value, Succ<typename Div<typename Sub::Value, N2>::Value>, Zero>::Value;
using Rem = typename If<typename GreaterEqual::Value, typename Div<typename Sub::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
struct Decimal_X {
using Value = typename Decimal_X::Value, D>::Value, R...>::Value;
};
template
struct Decimal_X < N, D > {
using Value = typename Add::Value, D>::Value;
};
template
struct Decimal {
using Value = typename Decimal_X::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 > {
using Value = H;
};
// Pair Tail
template <class Pair>
struct Tail;
template <class H, class T>
struct Tail < Pair > {
using Value = T;
};
// List
template <class Head, class... Tail>
struct List {
using Value = Pair < Head, typename List::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 > {
using Value = typename ListToDecimal_X<typename Add<typename Mul::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::Value;
};
/*************************************************
Algorithm
*************************************************/
// List Length
template <class List>
struct Length;
template <class H, class T>
struct Length < Pair > {
using Value = Succ < typename Length::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, Pair > {
using Value = typename Nth::Value;
};
template <class N>
struct Nth < N,Nil > {
using Value = Nil;
};
template <class H, class T>
struct Nth < Zero, Pair > {
using Value = H;
};
// List Drop
template <class N, class List>
struct Drop;
template <class N, class H, class T>
struct Drop < Succ, Pair > {
using Value = typename Drop::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, List > {
using Value = Pair < H, typename Concat::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 > {
using Value = Pair < typename F::Value, typename Map::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 FoldLefttypename Ftypename 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 Filtertypename L::Tail>::Value>,
typename Filtertypename 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::Value, N1, N2>::Value;
};
// Min
template <class N1, class N2>
struct Min {
using Value = typename If<typename LessThan::Value, N1, N2>::Value;
};
// Is_Odd
template <class N>
struct Is_Odd {
using Value = typename Equal<typename Div::Rem, i1>::Value;
};
// Is_Even
template <class N>
struct Is_Even {
using Value = typename Equal<typename Div::Rem, i0>::Value;
};
// Is_Integer
template <class N>
struct Is_Integer {
using Value = False;
};
template <class N>
struct Is_Integer < Succ > {
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 > {
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 > {
const static int ToInt = Integer::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::ToInt << std::endl;
}
};
// Display Boolean
template <class B>
struct DisplayBoolean {
inline static void Display() {
if (Boolean::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 > {
inline static void Display() {
if (Is_Integer::Value::ToBool) {
std::cout << Integer::ToInt << " ";
}
else if (Is_Boolean::Value::ToBool) {
if (Boolean::ToBool) std::cout << "true ";
else std::cout << "false ";
}
DisplayList::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();