4.1.用函数模拟自然数,习题详解

代码:
// 2.布尔值,如果
// 如果 [条件]为……真或假 那么 [选择一] 否则 [选择二]
// (选择一,选择二)中,如果 条件为……真,那么 [选择一]
// (选择一,选择二)中,如果 条件为……假,否则 [选择二]
真 = (选择一,选择二)=>选择一;
假 = (选择一,选择二)=>选择二;
如果 = (条件,选择一,选择二)=>条件(选择一,选择二);
真(上天=>上天,入地=>入地);//上天=>上天
((选择一,选择二)=>选择一)(上天=>上天,入地=>入地);
上天=>上天;
真(好=>好,坏=>坏);//好=>好
假(好=>好,坏=>坏);//坏=>坏
如果(真,上天=>上天,入地=>入地);//上天=>上天
((条件,选择一,选择二)=>条件(选择一,选择二))(真,上天=>上天,入地=>入地);
真(上天=>上天,入地=>入地);
上天=>上天;
如果(假,上天=>上天,入地=>入地);//入地=>入地
// 3.1.真值表
非 = (条件)=>如果(条件,假,真);
非(真);//假
如果(真,假,真);
非(假);//真
如果(假,假,真);
//为什么赋值语法很有用?
非(非(真));
非(假);
真;
//展开后
非(非(真));
((条件)=>如果(条件,假,真))(((条件)=>如果(条件,假,真))(真));
((条件)=>((条件,选择一,选择二)=>条件(选择一,选择二))(条件,假,真))(((条件)=>((条件,选择一,选择二)=>条件(选择一,选择二))(条件,假,真))(真));
((条件)=>((条件,选择一,选择二)=>条件(选择一,选择二))(条件,((选择一,选择二)=>选择二),((选择一,选择二)=>选择一)))(((条件)=>((条件,选择一,选择二)=>条件(选择一,选择二))(条件,((选择一,选择二)=>选择二),((选择一,选择二)=>选择一)))((选择一,选择二)=>选择一));
((条件)=>((条件,选择一,选择二)=>条件(选择一,选择二))
(条件,((选择一,选择二)=>选择二),((选择一,选择二)=>选择一)))
(((条件)=>((条件,选择一,选择二)=>条件(选择一,选择二))
(条件,((选择一,选择二)=>选择二),((选择一,选择二)=>选择一)))
((选择一,选择二)=>选择一));
// 3.2.或,条件一,条件二任意一个真,那么为真,否则为假
或 = (条件一,条件二) =>
如果(条件一,真,如果(条件二,真,假));
或(真,真);//真
如果(真,真,如果(真,真,假));
真;
或(真,假);//真
或(假,真);//真
或(假,假);//假
// 3.2.与,条件一,条件二都为真,那么为真,否则为假
与 = (条件一,条件二) =>
如果(条件一,如果(条件二,真,假),假)
与(真,真);//真
与(真,假);//假
与(假,真);//假
与(假,假);//假
// 第三部分:构建自然数
//2.零
零=道=>道;
//3. 0~6
零;// 0
加=>零;//1
加=>加=>零;//2
加=>加=>加=>零;//3
加=>加=>加=>加=>零;//4
加=>加=>加=>加=>加=>零;//5
加=>加=>加=>加=>加=>加=>零;//6
()=>零;//1
()=>()=>零;//2
()=>()=>()=>零;//3
()=>()=>()=>()=>零;//4
()=>()=>()=>()=>()=>零;//5
()=>()=>()=>()=>()=>()=>零;//6
(()=>零)()
零
//4.前继 函数
//前继(加=>加=>零) 加=>零
前继 = 自然数=>自然数()
//5.后继 函数
//后继(加=>加=>零); 加=>加=>加=>零;
自然数=>加=>自然数;
后继 = 自然数=>()=>自然数;
//6.1.加法 3+1
加=>加=>加=>零;
加=>加=>加=>加=>零;
后继(加=>加=>加=>零);//后继(3) 结果 4
//6.2.加法 3+2 = 3+1+1
加=>加=>加=>零;
后继(后继(加=>加=>加=>零));
//6.3.加法 3+3 = 3+1+1+1
加=>加=>加=>零;
后继(后继(后继(加=>加=>加=>零)));
//6.4.加法?
// (数一,数二)=> 后继(后继(后继(数一)))...
// 加(三,零) 三
// 加(三,一)
// 加(后继(三),前继(一))
// 加(四,零)
// 加(三,二)
// 加(四,前继(二))
// 加(五,前继(前继(二)))
// 加(五,零)
// todo 待实现
为零=(自然数)=>自然数===零?真:假;// 后面解释或替换掉这个函数.
// def 为零(自然数):
// if(自然数 == 零):
// return 真
// else:
// return 假
加 = (数一,数二) =>
如果(为零(数二)
,数一
,加(后继(数一),前继(数二))
);
零;// 0
一 = 加=>零;//1
二 = 加=>加=>零;//2
三 = 加=>加=>加=>零;//3
四 = 加=>加=>加=>加=>零;//4
五 = 加=>加=>加=>加=>加=>零;//5
加(三,二);
((数一,数二) =>
如果(为零(数二)
,数一
,加(后继(数一),前继(数二))
))(三,二);
如果(为零(二)
,三
,加(后继(三),前继(二))
);
加(后继(三),前继(二));
加(四,一);
((数一,数二) =>
如果(为零(数二)
,数一
,加(后继(数一),前继(数二))
))(四,一);
如果(为零(一)
,四
,加(后继(四),前继(一))
);
加(后继(四),前继(一));
加(五,零);
((数一,数二) =>
如果(为零(数二)
,数一
,加(后继(数一),前继(数二))
))(五,零);
如果(为零(零)
,五
,加(后继(五),前继(零))
);
如果(真
,五
,加(后继(五),前继(零))
);
如果(为零(零)
,五
,加(后继(五),前继(零))
);
//加(后继(五),前继(零),依然会被执行
加(后继(五),前继(零));
((数一,数二) =>
如果(为零(数二)
,数一
,加(后继(数一),前继(数二))
))(六,前继(零));
如果(为零(前继(零))
,六
,加(后继(六),前继(前继(零)))
)
加(后继(后继(五)),前继(前继(零)));
加(后继(后继(后继(五))),前继(前继(前继(零))));
// 发生了什么...
// 永远执行下去
// 7.重新定义真假,如果
如果(真, 五, 加(后继(五),前继(零)));
真 = (选择一,选择二)=>选择一;
假 = (选择一,选择二)=>选择二;
// 使得第二个参数不要被调用
真(五,加(后继(五),前继(零)));
(懒惰执行)=>加(后继(五),前继(零));
真((懒惰执行)=>五,(懒惰执行)=>加(后继(五),前继(零)));
(懒惰执行)=>五;
真 = (选择一,选择二)=>选择一(零);
真(()=>五,()=>加(后继(五),前继(零)));
真 = (选择一,选择二)=>选择一();
真(()=>五,()=>加(后继(五),前继(零)));
(()=>五)()
五
// ((懒惰执行)=>加(后继(五),前继(零)))(零)
// 加(后继(五),前继(零))
真 = (选择一,选择二)=>选择一();
假 = (选择一,选择二)=>选择二();
// 选择一
// 选择二
// 都需要懒惰执行,()=>
// 以前好多函数都要重新定义...
如果 = (条件,选择一,选择二)=>条件(选择一,选择二);
// 3.1.真值表
非 = (条件)=>如果(条件,()=>假,()=>真);
非(真);//假
非(假);//真
// 3.2.或,条件一,条件二任意一个真,那么为真,否则为假
或 = (条件一,条件二) =>
如果(条件一,()=>真,()=>如果(条件二,()=>真,()=>假));
或(真,真);//真
或(真,假);//真
或(假,真);//真
或(假,假);//假
// 3.2.与,条件一,条件二都为真,那么为真,否则为假
与 = (条件一,条件二) =>
如果(条件一,()=>如果(条件二,()=>真,()=>假),()=>假)
与(真,真);//真
与(真,假);//假
与(假,真);//假
与(假,假);//假
// 7.定义加减乘,相等,大于,小于
加 = (数一,数二) =>
如果(为零(数二)
,()=>数一
,()=>加(后继(数一),前继(数二))
);
减 = (数一,数二) =>
如果(为零(数二)
,()=>数一
,()=>减(前继(数一),前继(数二))
);
为一 = (自然数) => 如果(为零(自然数)
,()=>假
,()=>如果(为零(前继(自然数))
,()=>真
,()=>假)
);
乘非零 = (数一,数二) =>
如果(为一(数二)
,()=>数一
,()=>乘非零(加(数一,数一),减(数二,一))
);
乘 = (数一,数二) =>
如果(为零(数二)
,()=>零
,()=>乘非零(数一,数二)
);
相等=(数一,数二)=>如果(
与(为零(减(数一,数二)),
为零(减(数二,数一)))
,()=>真
,()=>假);
小于=(数一,数二) => 如果(
与(为零(减(数一,数二)),
非(为零(减(数二,数一))))
,()=>真
,()=>假);
大于=(数一,数二) => 如果(
与(非(为零(减(数一,数二))),
为零(减(数二,数一)))
,()=>真
,()=>假);
// 斐波那契数
// 第一个月初有一对刚诞生的兔子
// 第二个月之后(第三个月初)它们可以生育
// 每月每对可生育的兔子会诞生下一对新兔子
// 兔子永不死去
// 过了100个月,总计有多少兔子?
//1,1,2,3,5,8,13,……,斐(第88个月),斐(第89个月),斐(第88个月)+斐(第89个月),
斐波那契数 = (第几个月) =>
如果(或(为零(第几个月),为一(第几个月)),
()=>一,
()=>加(斐波那契数(减(第几个月,一))
,斐波那契数(减(第几个月,二)))
);