Scheme 编程/抽象与数据
外观
为了展示如何构建数据抽象,我们将逐步创建一个复数包。复数包含两个部分,实部和虚部。它们通常以两种方式之一表示,直角坐标形式
和极坐标形式
现在,我们可以对复数执行所有常见的算术运算,加法、减法、乘法和除法。它们有简单的公式;
加法
减法
乘法
除法
请注意,乘法和除法最好用极坐标形式表示,而加法和减法最好用直角坐标形式表示。这就提出了一个有趣的问题:如何最好地计算这些?我们是否使用一种内部表示?如果是,我们选择哪一种?有很多问题需要解决。这些可以通过尝试实现一种新的数据类型来解决:复数类型。
首先,我们将创建一个通用“类型”变量
(define typed-variable
(lambda (type value)
(cons 'Typed (list type value))
)
)
现在我们需要一种方法来判断给定变量是否具有类型
(define typed?
(lambda (var)
(and (list? var) (= 'Typed (car var)))
)
)
现在,我们已经引入了两个重要的概念,“谓词”和“构造函数”。第一个是用于判断某些数据是否具有正确形式的结构,第二个是用于构建我们数据结构的程序。
我们必须有一种方法来提取我们的数据(在本例中,是类型)从这种结构中,一种“选择”它的方法
(define type-of
(lambda (var)
(if (typed? var)
(car (cdr var)
)
)
)
使用此类型的值,我们可以继续为我们的复数形成更详细的数据结构
(define complex-rect
(lambda (a b)
(typed-variable 'Rect-Complex (list a b))
)
)
现在让我们继续,并创建一个complex-polar
(define complex-polar
(lambda (r thet)
(typed-variable 'Polar-Complex (list r thet))
)
)
(define complex
(lambda (type first-var second-var)
(if (equal? 'type Polar)
(cons (complex-polar first-var second-var)
(complex-rect (sqrt (+ (expt first-var 2)
(expt second-var 2)
)
)
0
)
) ;; Change second half to be the calculated values.
(cons (complex-polar 0 0) (complex-rect first-var second-var))
)
)
)
我们拥有了构造函数,现在我们需要谓词
(define is-complex?
(lambda (var)
(and (typed? (car var))
(or (= 'Rect-Complex (type-of (car var)))
(= 'Polar-Complex (type-of (car var)))
)
)
)
)
现在我们可以根据这些程序定义算术运算。