元 我的定义(参数列表)//命名的参数化的代码块.
{
构 树{...}
树 树上映射(树 输入,树 闭包(树)f){...}
空 打印树(树 输入){...}
别名 树数组=树[];
}
这样,定义.编译时参数列表可为类型,别名(符号),字面量,T...
,允许编译时
的一切.别名参数允许捕获数组,类,函数,结构名
,并使用他们的能力.
模板主体除了模块
,基本上啥都可以.实例化时才检测语义.枚 串 名
表明是编译时
.常/不变
是存储类,表示不变
,记住模板不能在函数中声明
.
实例化模板.用!(编译时参数)
,只1参,可省略括号.
模板作为模板参数
,类似策略类
了.实例化模板后,就建立了命名域(代码块)
,应用存储类,初化变量
应多借助alias,类似c++的用
.c++/d的实例化是都生成代码.而java/c#
的泛型是擦除类型.相同编译时参数只生成一次代码.空
可以为模板参数,然而没啥用.可以限定特定模板参数
.比如概念/各种条件
.
元 双(T)
{
T[] 双(T t) { 中 [t,t];}
//仅一个双成员
}
动 数组 = 双!(整)(1);//就像c++的构造函数一样
这样.
元 记录(T, U, V)
{
导入 标.构造类型: 大元组, 元组;
别名 大元组!(T,U) 双;
别名 双[V] 关联数组;
别名 关联数组[] 记录;
}
记录!(整,串,双精[]) 记录单列;//这样
元 的所有数组(T)
{
别名 T 元素;
别名 T* 指针;
别名 T[] 动态数组;
别名 T[1] 静数组;
别名 T[T] 关联数组;
}//就可以实例化后用`.元素`
静 如
类似如 常式()
,注意:实例化后没括号
,这里并没有建立一个域(有限制)
.一个语句,则可删除{}
静 如 (有长度!R) //跟随内部区间有/无长度
动 长度()
{
中 内部区间.长度;
}
静 如 (是无限!R) //是无穷?
枚 极 空的 = 假;
元 秩(T)
{
静 如(是(T t == U[], U))//数组?
枚 大小型 秩 = 1 + 秩!(U);//递归+1
异
枚 大小型 秩 = 0; //否则为0
}
静断
用来编译时检测是否满足条件.与断定
差不多.
导入 标.区间;
元 秩(T)
{
静 如 (是输入区间!T)//区间,通过T的元素类型
枚 大小型 秩 = 1 + 秩!(元素类型!T);//递归
异
枚 大小型 秩 = 0;//
}
元 基元素类型(T)
{
静 如 (秩!T == 0)//基
静 断定(0, T.的串 ~"不是区间.");
异 静 如 (秩!T == 1) //简单区间
别名 元素类型!T 基元素类型;
异 //递归
别名 基元素类型!(元素类型!(T)) 基元素类型;
}//求最基元素类型
元 n维数组(T, 大小型 r)
{
静 如 (r == 0)
别名 T n维数组;
异
别名 n维数组!(T, r-1)[] n维数组;
}//递归传[],生成N维数组
多次函数,
导入 重复组合;
// 标准函数,参数与返回值一样
串 福(串 s) { 中 s ~ s;}
数组[] 造数组(数组)(数组 数组) { 中 [数组,数组];}
空 主()
{
断定(幂!(福,0)("a") == "a"); // 身份 函数
断定(幂!(福,1)("a") == 福("a"));
断定(幂!(福,2)("a") == 福(福("a")));
断定(幂!(福,3)("a") == 福(福(福("a"))));
断定(幂!(造数组, 0)(1) == 1);
断定(幂!(造数组, 1)(1) == [1,1]);
断定(幂!(造数组, 2)(1) == [[1,1],[1,1]]);
断定(幂!(造数组, 3)(1) == [[[1,1],[1,1]],[[1,1],[1,1]]]);
}
元 幂(别名 函数, 正 指数)
{
静 如 (指数 == 0) //退化
动 幂(实参)(实参 实参) { 中 实参; }
异 静 如 (指数 == 1) //1
别名 函数 幂;
异
动 幂(实参...)(实参 实参)
{
中 .幂!(函数, 指数-1)(函数(实参));
}//幂为返回值.
}//三个分支都暴露了`幂`.,
幂
定义了同名模板,隐藏了外部父同名幂
,而.幂
是全局父模板名,这里调用的是父模板名..
为全局域
操作符.不仅单参
,N参
,闭包
,定义了()
的构/类
,或模板函数
都可以用.柯里化?
,给定一个模板
,可以生成一个柯里化的模板
.
元 元素类型(T : U[], U) //针对数组
{
别名 U 元素类型;
}
元 元素类型(T : U[n], U, 大小型 n) //静态数组
{
别名 U 元素类型;
}
类 数组 { 别名 整 元素类型;}
元 元素类型(T : 数组)//特定数组
{
别名 数组.元素类型 元素类型;
}
模块 限定2;
元 内部类型(T : U*, U) //指针
{
别名 U 内部类型;
}
元 内部类型(T : U[], U) // 动态数组
{ /*...*/ }
元 内部类型(T) // 标准默认.
{ /*...*/ }
空 主()
{
整* p;
整 i;
别名 内部类型!(的型(p)) 指针; // 用指针
别名 内部类型!(的型(i)) 默认; // 用标准
}
上面是模板特化
,模板也可有默认值.
元 默认(T = 整, 极 标志 = 假)
{
静 如 (标志)
别名 T 默认;
异
别名 空 默认;
}
别名 默认!(双精) D1;// 实例化 默认!(双精, 假)
别名 默认!(双精,真) D2;//实例化 默认!(双精, 真)
别名 默认!() D3;//实例化 默认!(整, 假)
可自动推导.
元 推导(T : U[], V = T, U)
{
别名 元组!(T,U,V) 推导;
}
别名 推导!(整[], 双精) D1;// U,整, V,双精.
别名 推导!(整[]) D2; // U 整. V也是整,
元 我的函数(T, 整 n)
{
动 我的函数(T t) { 中 到!整(t) * n;}
}//不够简洁.
串 连接(A,B)(A a, B b)//第一个括号为`模板参数`
{
中 到!串(a) ~ 到!串(b);
}//这样
参 选择(串 如何 = "最大", 参)(参 参0, 参 参1)
{
静 如 (如何 == "最大")
中 (参0 < 参1) ? 参1 : 参0;
异 静 如 (如何 == "最小")
中 (参0 < 参1) ? 参0 : 参1;
异
静 断定(0,
"只能为最大/最小");
}
也可模板返回类型
,见下,返回依赖(T,U),类似c++常式
返回了.
动 变形(别名 f, T, U)(U 参)
{
静 如 (是(T == 类))中 新 T(f(参));
异 静 如 (是(T == 构))中 T(f(参));
异 中; // 返回空函数.
}
还有动 引用
,函数模板可有动 引用
模板参数.对左值
,取引用
版本.隐式模板实例
,根据运行时参数
,推导编译时参数
.
串 资源1 = 连接(1, 3.14); //整,双精
串 资源2 = 连接("abc", 福()); //串,福
动 资源3 = 选择(3,4); //"最大",整
动 资源4 = 选择!"最小"(3.1416, 2.718)//最小,
记住,(T)模板
不是(T)
,T:函数,构,类,接口,联
,他们是模板
,模板是参数化的域
,域
不是一等公民.无类型,不能赋值给变量,不能从函数返回.不能返回函数模板
,不能继承类模板
.实例化后,一切都有了.
动 变平(数)(数 数组)//变平数组
{
静 如 (秩!数 <= 1)中 数组;
异
{
动 子 = 映射!(.变平)(数组);//又是(.)
中 简化!"a~b"(子); // 连接子
}
}
练习,添加一个级数
作为编译时参数,变平几级
,或者变平为几级
.
动 添加者(整 a)
{
中 (整 b) { 中 a+b;};
}
动 添加者(T)(T a)
{
中 (T b) { 中 a+b;};
}//模板了.
单元测试
{
动 加1 = 添加者(1); //加1是闭包,非模板
断定(加1(2) == 3);
}
匿名模板函数(a,b) { 中 a+b;}
,类似c++的(动 a,动 b){...}
的λ
函数.不能 别名 (a){ 中 a;} 标识; // 错误
,这是模板
,不能返回.好处是,闭包
,可捕捉局部变量
.
c++就是这样,你的λ
就可以这样.
闭包是穷人的对象.我们用命名参数
创建返回元组的对象.
动 造计数器(T)(T _计数器 = T.初化) 如 (是数值!T)
{
极 感觉 = 真;
动 改变感觉 = () { 感觉 = !感觉;};
动 包含 = (T 加)
{ _计数器 += (感觉 ? 加 : -加); };
动 减少 = (T 减少)
{ _计数器 += (感觉 ? -减少 : 减少); };
动 计数器 = (){ 中 _计数器;};
中 元组!( 的型(改变感觉), "改变感觉"
, 的型(包含), "包含"
, 的型(减少), "减少"
, 的型(计数器), "计数器")
(改变感觉, 包含, 减少, 计数器);
}
折腾,一个类,就完
了.没必要.还有重载函数
可以自定义存储类
.
元 初化(T)
{
静 如 (是(T == 不变) || 是(T == 常))
空 初化(T t) {} //空的
异 静 如 (是(T == 类))
空 初化(引用 T t)
{
t = 新 T();
}
异{
空 初化(引用 T t){
t = T.初化;
}
}
}
d中自动推导属性.@纯
表无副作用.只需要关心返回值
.@安全
表示不会破坏内存.@不抛
不抛异常.
编译器可自动推导属性.实例化后函数随参数中属性变化而变.in/out
用于断定满足条件
.
动 元组化(F,T...)(元组!T 元组)
{
中 F(元组.扩展);//元组.扩展
}
动 n映射(别名 函数, R...)(R 区间) 如 (都满足!(是输入区间,R))
{
中 映射!(元组化!函数)(压缩(区间));
}
动 n映射(函数..., R...)(R 区间) 如 (都满足!(是输入区间, R))
{ ... } //不行
元 n映射(函数...) 如 (函数.长度 >= 1)//条件
{
动 n映射(R...)(R 区间) 如 (都满足!(是输入区间, R))
{...}
}
类似c++的元与值<...>
可以这样解决双<...,...>
元 n映射(函数...) 如 (函数.长度 >= 1)
{
动 n映射(R...)(R 区间) 如 (都满足!(是输入区间, R)){
别名 邻接!(静映射!(元组化, 函数)) _函数;
中 映射!(_函数)(压缩(区间));
}
}
同样c++
应该也可以这样解决
,只不过用构
.型列<...>
可能也是一种解法.
动 n过滤(别名 函数, R...)(R 区间) 如 (都满足!(是输入区间, R))
{
中 过滤!(元组化!函数)(压缩(区间));
}//简单过滤
构模板:
构 树(T)//加上参数.
{
T 值;
树[] 子;//意思为当前实例.即(树==树!T)
极 是叶子() @属性 { 中 子.空的;}
}
动 t0 = 树!整(0); // 是.
动 t1 = 树(0);
动 树(T)(T 值, 树!T[] 子=空)
{
中 树!(T)(值, 子);
}
用模板函数
,模板构造可能与全局模板参数
不一样.推断不出来.
构 树(T)
{
别名 T 类型;//允许外部访问原模板参数
T 值;
树[] 子;
极 是叶子() @属性 { 中 子.空的;}
}
模板构,里面可以有模板成员函数
.这是c++
强大的基础
动 树(T)(T 值, 树!T[] 子 = 空)
{
中 树!(T)(值, 子);
}
构 树(T)
{
别名 T 类型;
T 值;
树[] 子;
极 是叶子() @属性 { 中 子.空的;}
树!(的型(函数(T.初化))) 映射(别名 函数)()
{
别名 的型(函数(T.初化)) 映射类型;
映射类型 映射值 = 函数(值);
树!(映射类型)[] 映射子;
每一(子; 子) 映射子 ~= 子.映射!(函数);
中 树(映射值, 映射子);//返回树
}//遍历了树.
}
类似c++的推导(动)
整 加一(整 a) { 中 a+1;}
空 主()
{
动 t0 = 树(0);
动 t1 = 树(1, [t0,t0]);
动 t2 = 树(2, [t1, t0, 树(3)]);
//一下就操纵了整棵树
动 t3 = t2.映射!(加一);
动 ts = t2.映射!(到!串);
树!(T) 树(T)(T 值, 树!T[] 子 = 无效)
{
中 树!(T)(值, 子);
}
构 树(T)
{
别名 T 类型;
T 值;
树[] 子;
极 是叶子() @属性 { 中 子.空的;}
的型(如叶子(T.初化, S.初化))
折叠(别名 如叶子, 别名 如分支 = 如叶子, S)(S 种子)
{
如(是叶子){//判断当前节点
中 如叶子(值, 种子);//@1
}异{
的型(树.初化.折叠!(如叶子, 如分支)(种子))[] 折叠子;//存储
每一(子; 子)
折叠子 ~= 子.折叠!(如叶子, 如分支)(种子);//是递归
中 如分支(值, 折叠子);//干活@2
}
}
}//折叠
先序,后序,树高,叶总数,对区间,折叠很灵活
,需要一个种子+两个折叠函数
(是叶子,是分支).
使用:
的型(T.初化 + S.初化)
叶子和(T, S)(T 值, S 种子)
{
中 值 + 种子;
}
T 分支和(T)(T 值, T[] 子和)
{
中 值 + 简化!"a+b"(子和);
}//求和
空 主()
{
动 t0 = 树(0);
动 t1 = 树(1, [t0,t0]);
动 t2 = 树(2, [t1, t0, 树(3)]);
整 和 = t2.折叠!(叶子和, 分支和)(0);
断定(和 == 2 + (1 + 0 + 0) + (0) + (3));
}
T[] 按l序(T, S)(T 值, S 种子)
{
中 [值] ~ 种子;
}
T[] 按b序(T)(T 值, T[][] 按子序)
{
中 [值] ~ 简化!"a~b"(按子序);
}
空 主()
{
动 t0 = 树(0);
动 t1 = 树(1, [t0,t0]);
动 t2 = 树(2, [t1, t0, 树(3)]);
整[] 种子; // 空数组
动 有序 = t2.折叠!(按l序, 按b序)(种子);
断定(有序 == [2, 1, 0, 0, 0, 3]);
}//相当于变平了.
模板构造函数,c++也行的
.
构 S(T)
{
本(U)(U u) { /*...*/ }
//构造函数外不能用U,
}
空 主()
{
动 s = S!串(1); // T是串,U是整.
}
更有用的是 用别名(函数)
来初化构.
构 持有者(类型)
{
类型 值;
本(另一类型)(另一类型 _值)
{
值 = 到!类型(_值);//构造时转换,
}//其他类型都转成`类型`了
}
动 堆(别名 判断, 类型)(类型[] 值)
{
构 堆
{
类型[] 值;
本(类型[] _值)
{
...
}//初化代码
}
中 堆(值); //
}//内部构,没啥用.
动 连接(A)(A a)
{
中 (B)(B b) { 中 到!串(a) ~ 到!串(b);};
//非法D代码,这是模板
}
动 连接(A)(A a)
{
构 连接器
{
A a;
动 调用操作(B)(B b) @信任
{
中 到!串(a) ~ 到!串(b);
}
}//多此一举.
连接器 c;
c.a = a; // 为了不`调用操作()`
中 c;
}
直接构模板+成员模板
不一样吗?
构 外部(O)
{
O o;
构 内部(I)
{
O o;
I i;
}
动 内部(I)(I i) { 中 内部!(I)(o,i);}
}
构在内部,没啥必要.在外部有何不可?
区间:
构 变平(区间)
{
区间 区间;
/*...*/
}
动 变平(区间)(区间 区间)
{
静 如 (秩!区间 == 0)
静 断定(0, "变平必须是区间.");
异 静 如 (秩!区间 == 1)
中 区间;
异
中 变平!(区间)(区间);
}
控制变平返回顺序.
构 变平(区间)
{
别名 元素类型!区间 子区间;
别名 元素类型!子区间 元素;
区间 区间;
子区间 子区间;
本(区间 _区间) {
区间 = _区间;
如 (!区间.空的) 子区间 = 区间.前;
}
元素 前() { 中 子区间.前;}
极 空的() { 中 区间.空的;}
空 弹前() {
如 (!子区间.空的) 子区间.弹前;
当(子区间.空的 && !区间.空的) {
区间.弹前;
如 (!区间.空的) 子区间 = 区间.前;
}
}
}
动 变平(区间)(区间 区间)
{
静 如(秩!区间 == 0)
静 断定(0, "变平要求区间.");
异 静 如 (秩!区间 == 1)
中 区间;
异 静 如 (秩!区间 == 2)
中 变平!(区间)(区间);
异 // 秩>=3
中 变平(变平!(区间)(区间));
}//加递归,
1个大变平,1个小变平
,D的继承,不能用多继承
类 基 {}
接口 接口1 {}
接口 接口2 {}
类 我的类(类型, 别名 函数, 极 b = 假)
: 基, 接口1, 接口2
{ /*...*/ }
类 基(T) {}
接口 接口1 {}
接口 接口2(别名 函数, 极 b) {}
//接口模板,其实,类似策略类了.
类 我的类(类型, 别名 函数, 极 b = 假)
: 基!(类型), 接口1, 接口2!(函数,b)
{ /*...*/ }
模块 类语法3;
枚 什么是基 { 对象, 接口, 基类 }
元 基(什么是基 什么基 = 什么是基.对象)
{
静 如 (是(T == 什么是基.对象))
别名 对象 基; // 我的类直接从对象继承
异 静 如(是(T == 什么是基.接口))
别名 接口 基;
异
别名 基 基;
}
类 我的类(类型) : 基!类型 {}
有点类似策略类
的基抽象类了
,可更加细化调度模板
,就是不能编译时
更改接口数量.
很难这样,用这个参数,类从I,J
继承.用那个参数,类从K
继承.可用类型元组
来简化他们.这个时候,可用串/模板
插件吧.对象方法
就是个带本
的闭包
.
类 我的类(T, U, V)
{
/*...*/
不变量 ()
{
静 如 (是(T == U))
{
/* 不变量代码 */
}
异
{ } /* 空的不变量 */
}
}
类不变量.
内部类,没啥用.
动 受者(别名 函数, D)(D 默认值)
{
中 新 类{//为啥不取个名?
本() {}
动 调用操作(T)(T t)
{
静 如 (__特征(编译, 函数(T.初化)))
中 函数(t);
异
中 默认值;
}
};//匿名类,没啥用.
}
接口 I可序化
{
大小型 序化() @属性;
}
类 可序化(T) : T, I可序化//T.
{
大小型 序化() @属性
{
中 本.至哈希;
}
}
动 包装 = 新 可序化!(可迭代!(一些类))(/*...*/);
继承了T
,就有T
的行为.
枚 序化策略 { 策略1, 策略2 }
接口 I可序化
(序化策略 策略 = 序化策略.策略1)
{
静 如 (是(策略 == 序化策略.策略1))
空 序化() { /*...*/ }
异
空 序化() { /*...*/ }
}
类 可序化(T, 策略) : T, I可序化!策略
{
/*...*/
}
通过继承
加功能
抽象 类 单元(T)
{
抽象 空 置(T 值);
抽象 常(T) 取();
私:
T 字段;
}//定义单元的子类模板.
类 加置器(C: 单元!T,T): C
{
盖 空 置(T 值){字段 = 值;}
}
类 加取器(C: 单元!T,T): C
{
盖 常(T) 取(){中 字段;}
}
类 双单元(C: 单元!T,T): C
{
盖 空 置(T 值){父.置(2*值);}
}
类 一加单元(C: 单元!T,T): C
{
盖 空 置(T 值){父.置(值+1);}
}
类 置器记录器(C:单元!T,T): C
{
盖 空 置(T 值)
{
父.置(值);
写行("单元置为'",值,"'!");
}
}
类 取器记录器(C:单元!T,T): C
{
盖 常(T) 取()
{
动 值 = 父.取();
写行("提取'",值,"'!");
中 值;
}
}
类 具体单元(T): 加取器!(加置器!(单元!T)){}
类 一加双置器(T): 一加单元!(双单元!(加置器!(单元!T))){}
类 双倍一加置器(T): 双单元!(一加单元!(加置器!(单元!T))){}
空 主()
{
单元!串 x;
x = 新 具体单元!串;
x.置("你好");
写行(x.取());
单元!整 y;
y = 新 置器记录器!(具体单元!整);
y.置(123); // 打印:
y = 新 取器记录器!(双单元!(具体单元!整));
y.置(1234);
y.取(); // 打印
y = 新 加取器!(一加双置器!整);
y.置(100);
写行(y.取()); // 打印 "202"
y = 新 加取器!(双倍一加置器!整);
y.置(100);
写行(y.取()); // 打印 "201"
}
与策略类,没啥区别
,策略类就是这样.继承体系下的为实现策略类
,一个基策略类
.具体类继承具体实现类
还可用模板插件/串插件
.
奇异模式.
模块 奇递归;
类 基(子) { /*...*/ }
类 继承 : 基!继承 { /*...*/ }
元 类树实现(叶子...)
{
静 如 (叶子.长度 > 1)
{
别名 元组类型!(叶子[0], 基类元组!(叶子[0]),
类树实现!(叶子[1..$])) 类树实现;
}
异
静 如 (叶子.长度 == 1){
别名 元组类型!(叶子[0], 基类元组!(叶子[0])) 类树实现;
}异{
别名 元组类型!() 类树实现;
}
}
元 类树(叶子...)
{
别名 继承至前!(无重复!(类树实现!(叶子))) 类树;
}
元 自动分发(叶子...)
{
空 自动分发(别名 函数, 实参...)(实参 实参)
如 (实参.长度 >= 1 && 是(实参[0] == 类))
{//第一个是类.
动 对象信息 = 具型(实参[0]);
每一 (基; 类树!叶子)
{
如 (对象信息 == 基.类信息)
{
静 如 (__特征(编译,
{//避免`静每一`的编译时错误
中 函数(转换(基)(转换(空*)实参[0]), 实参[1..$]); }//两个参数.一个实参0,一个剩余.
())
)//可编译
{
中 函数(转换(基)(转换(空*)实参[0]), 实参[1..$]);
}//能够编译,则运行.
}
}
串[] 实参;
实参 ~= 对象信息.至串();
每一 (参; 实参[1..$])
实参 ~= 的型(参).的串;
断定(0, 格式("不能用'(%s)调用'函数'%s'",__特征(标识符, 函数), 实参.合并(", ")));
}
}
空 主()
{
A c = 新 C;
A d = 新 D;
A a = 新 A;
别名 自动分发!(C, D) 调用函数;
调用函数!福(c, 1); // 好
调用函数!福(d, 2, 3); // 好
调用函数!福(a, 3); // 将 断定 在 运行时
}//这些c++都有,类似`应用/调用`(...)
仅对单对象
参数有用,但可扩展
为分发多对象
,感觉类似双/多分发
.提取叶类列表,并用特征
取树类
,然后分发单对象及其参数
到函数.
就是策略类的子类在前,去掉重复
,学了AA大神
的现代c++新思维
就是好,一眼就看出来了
,
接口 接口(T)
{
T 福(T);
T[] 条(T,整);
}
联 联(A,B,C) { A a; B b; C c;}
元 枚(T)
{
枚 枚 : T { A, B, C}
}
接口,联,枚
模板,类似的.