Scheme中的条件问题

时间:2013-11-10 04:30:11

标签: scheme

我正在使用带有完整Swindle包的Scheme,我正在尝试使用条件来递归地确定整数的均匀性/奇怪性。我的代码如下:

(define (odd? x)(
            (cond 
              ((= x 0) '#f)
              ((= x 1) '#t)
              ((= (even? (- x 1)) #t) '#f)
              (else '#t))))

(define (even? x)(
              (cond
                ((= x 0) '#f)
                ((= x 2) '#t)
                ((= (odd? (- x 1)) #t) '#f)
                (else '#t))))

然而,当我运行(甚至?x)或(奇数?x)[x是某个数字,无关紧要,因为我得到相同的错误]我得到:应用程序:不是程序;  期望一个可以应用于参数的过程   给出:#t   参数......:[无]

有人可以帮忙吗?谢谢。我不是100%熟悉理想的Scheme语法,所以可能就是这样。

2 个答案:

答案 0 :(得分:0)

cond表达式周围有一对错误的括号(导致报告错误)。但是,每个过程中都有太多条件,并且因为您使用=来比较具有布尔值的数字,所以会出现合同违规的点。要解决此问题,您可以在此处将=替换为equal?

((equal? (even? (- x 1)) #t) '#f)

在这里:

((equal? (odd? (- x 1)) #t) '#f)

但是,程序仍然会给出错误的结果:

(even? 5)
=> #t
(odd? 7)
=> #f

老实说,我认为最好简化实施,这将解决所有问题。试试这个:

(define (odd? x)
  (cond ((= x 0) #f)
        (else (even? (- x 1)))))

(define (even? x)
  (cond ((= x 0) #t)
        (else (odd? (- x 1)))))

现在我们会得到正确答案:

(even? 4)
=> #t
(even? 5)
=> #f
(odd? 6)
=> #f
(odd? 7)
=> #t

答案 1 :(得分:0)

括号中的任何Scheme表单都是应用程序,例如(sin 42)(42 sin)。第一个调用sin作为带参数42的函数并生成一个值;第二个尝试使用参数42调用sin,但42不是过程,因此这会导致错误。同样(42)是一个没有参数的应用程序;它仍然必须有一个程序作为第一部分应用,没有参数调用,对吧?在Scheme中,括号很重要,它们不仅仅用于分组内容(因为它们可能在其他语言中)。所以额外的括号会导致额外的尝试来评估结果,这是一个布尔值,即不是一个过程,所以这是一个错误。

然后,'#f只是#f;类似于#t(他们都评价自己);条件 (= test #t) 1 (equal? test #t)test相同(生成相同的布尔结果集) (( 1 我们不能使用=来比较布尔值,它应该仅用于数字))

(define (odd? x)
        (cond 
          ((= x 0) #f)
          ((= x 1) #t)
          ((even? (- x 1)) #f)
          (else #t)))

此外,(if test #f else...)(if (not test) else... #f)相同:

(define (odd? x)
        (cond 
          ((= x 0) #f)
          ((= x 1) #t)
          ((not (even? (- x 1))) #t)
          (else #f)))                 ; (else ...) is like (#t ...)

使用逻辑连词,可以合并具有相同结果的子句,并且可以重新排列互斥条款(可以通过明确的警卫实现互斥性):

(define (odd? x)
        (cond 
          ((and (/= x 0)              ; a guard
                (or (= x 1) 
                    (not (even? (- x 1))))) #t)
          ((or (= x 0) #t) #f)))

(cond (test #t) (else #f)(if test #t #f),仅为test

(define (odd? x) (and (> x 0)         ; `>` is better
                      (or (= x 1) 
                          (not (even? (- x 1))))))

警卫(> x 0)阻止了负x es的堕落。

但是,这是完全错误的。要使n为奇数,n-1 必须为偶数,而不是相反!

(define (odd? x) (and (> x 0)         ; work only for positive integers
                      (or (= x 1) 
                          (even? (- x 1)))))

我们可以编写(not (odd? (- x 1))),但它不会是尾递归的。它将<{em> tail recursive modulo cons not 作为“构造函数”),但对于某种历史性的侥幸 2 ,不需要TRMC优化的Scheme实现。 andor形式中的最后一个表达式实际上是in tail position。但不是not(( 2 尽管是described as early as 1974.))

even?的定义重复相同的内容。