在 SICP 中创建强制程序

Creating coercion procedures in SICP

这是 SICP 关于强制的引用。本节讲的是普通数、有理数、复数的算术包,以及对它们进行跨类型运算(例如,普通数加一个复数。)

This coercion scheme has many advantages over the method of defining explicit cross-type operations, as outlined above. Although we still need to write coercion procedures to relate the types (possibly N^2 procedures for a system with N types), we need to write only one procedure for each pair of types rather than a different procedure for each collection of types and each generic operation.

我对这一行感到困惑:

"possibly N^2 procedures for a system with N types"

我们以算术包为例。对两个普通数(scheme-number scheme-number)、两个有理数(rational rational)和两个复数(complex complex)的运算属于同一类型,因此不包括在强制转换程序中。

我们有三种类型,这些是我能想到的只有两个参数的强制程序。

(scheme-number rational) (方案编号复合体) (有理方案-编号) (理性情结) (复杂的方案编号) (复有理数)

这些不是 n^2 个强制程序。这里只有 6 个强制程序,而不是 9 个。我想我根本没有真正理解这部分文本。谁能解释一下我错过了什么?

最后,这里有一个关于这部分文本的脚注。

If we are clever, we can usually get by with fewer than N^2 coercion procedures. For instance, if we know how to convert from type 1 to type 2 and from type 2 to type 3, then we can use this knowledge to convert from type 1 to type 3. This can greatly decrease the number of coercion procedures we need to supply explicitly when we add a new type to the system.'

据我了解,如果我们可以将普通数转换为有理数,然后将该有理数转换为复数,我们就不需要将普通数转换为复数的过程。是吗?

谁能更清楚地解释一下?

第一部分我理解为 O(N^2):如果有 10 种类型,我们将需要大约 100 次操作(实际上是 90 次)。至于第二部分,你是对的:我们可以建立一个可组合的强制转换。然而,就我能想到的它的实现而言,这将需要建立一个有向图,其中节点 = 类型,边 = 强制。然后找到正确的强制转换将涉及遍历图形以找到从一个节点到另一个节点的路径(不便宜!)。

PS。使事情变得更加复杂:复杂和有理数都可以充当其他类型的容器,例如有理数的复数、整数的复数、整数的有理数(最简单的版本)、多项式的有理数等。然后强制问题变得更糟:考虑添加 1+2i、2/3 和 3.0 - 首先所有东西都需要转换成它们各自的复数表示(1+2i、2/3+0/1i、3.0+0.0i),然后才将其全部强制转换为复数内的浮点数……TL;DR:数字强制是一场噩梦,我很高兴我不必自己做!