Ruby 实现多态,用匹配子来理解类型理论——类型论(二)

目录:
- Haskell 类型系统的不足
- Ruby 函数多态的类型实现 | 类型 与 Matchy,参数 与 Serie
- 实现 参数数量的多态
Haskell 的函数的类型如下,它可以实现类型多态
我们把这六个分支叫做函数的分态 或者 分支函数。
但我们不可以进行如下定义:
因为 Haskell 的所有函数本质都是一元函数,这是它实现 函数curry(柯里)化 的理论和原理。
二元函数接受一个值,返回一个一元函数。
因为 func 接受一个 int 值之后,无法确定 要返回 int 还是 int -> int、
因此,Haskell 无法完美实现 参数数量的多态。
我们要实现 更完全 的多态,不能使用 函数纯一元 的设定。
如 Ruby 要实现数量多态是这样的。
如下,是一个合法的 Ruby 函数定义和其调用。
我们把定义部分的 (a, b, c, *args, &blk),叫做 匹配子(Matchy)
而调用部分的 (a, b, c, d, e) 叫做 Serie(系列)。
blk.call(...)中的(a, b, [c, *args].sum) 叫做 打包(Packy)
Serie 需要通过 匹配子 匹配成功后,才能成功地调用 函数。
之后 Serie 经过 打包,传输给 函数体进行处理。
这里,匹配子 等同于 函数的类型。
Serie -> Matchy -> Packer -> Proc
之后 Proc 再输出 Serie 给调用这个函数的函数。
为方便起见,匹配子的书写为 Matchy(...)
系列的书写为 Serie(...)

现在,我们要在 Ruby 中实现复杂的函数多态系统。
这是我自己写的一个库。

着手用 Ruby 实现函数多态
我们可以在 Ruby 中 定义函数多态,以代替在函数内部重复书写的 if-else,
以及每次增加新功能都要增改函数定义、或者 给原函数起别名 的麻烦。
其中 Numeric, Numeric, Numeric => Numeric是 匹配子。
这个匹配子包含了返回值类型,用以根据调用它的下游函数所需要的参数类型,返回特定的分态。
可以看到,伪关键字 main 表示函数的主函数,而 mu 则表示分支函数。这个main 和 mu 在具体的实现上只是一种语法盐,方便理清关系。
Numeric, Numeric, Numeric 是函数的输入匹配子。
=> 右边的 Numeric 是函数的返回匹配子。
这表明,log 如果接受三个 Numeric 参数,以及下游调用者需要一个 Numeric 参数
则 调用 模式为 Matchy( Numeric, Numeric, Numeric => Numeric )的分支函数 进行计算。
(但是目前只实现了参数多态,尚未实现返回值多态)
可知,Numeric 是一个类(Class),而 1, 2, 3 是他的实例。
在Ruby 中,任何类的类都是类类(Class),都是Class 的实例,而任何不是类的对象,都可以当作值。
Ruby 的模式匹配是
类类的实例 匹配 他的实例,即,类 匹配于 其 实例。
类类 匹配 类。
可以看到
Class 不是 任何非类实例的超父类
1. 类自身 无法匹配 类自身
2. 类 可以匹配 类实例
3. 非类实例 可以 匹配 非类实例自身
如何让 Numeric 匹配 Numeric 呢
这时,需要指示 匹配函数,match(matchy, serie),matchy 中的类当作非类实例看待。
Just(Numeric) 可以匹配 Numeric
目前还没有实现 in 的这个功能。
Just(Numeric) 等价于 Numeric 的单例类。所以可以匹配成功。
理论上,匹配子 1, 2 表示匹配1 和 2的实例。而 1 和 2 不是类,显然没有实例。
但在Ruby中,非类实例 的匹配其自身。
因此不需要写 Just(1), Just(2),Matchy(1, 2) 就可以 匹配 Serie(1, 2) 了。

参数数量标记,用 正则表达式 来理解
Numeric {3} 表示 接收三个连续的 Numeric 实例
Numeric * 表示接受0个或多个连续的 Numeric 实例
在 Ruby 中的写法是
Some(quant, class) 指示 匹配0到2个连续的 Float 实例
当输入的参数 Serie 匹配于 Matchy(Float, Some(..2, Float))时,就会调用该函数。

那么,假设 函数对 参数的部分顺序并不关心,该如何描述呢?
例如,加法,排序函数。
无论输入的参数是怎样的顺序,输出的结果都是一样。

下回:更复杂的类型实现:
- 交换律、结合律、幂律....
- 类型的并、单匹配子,母匹配子,子匹配子,匹配子的解茧。