首页 > 解决方案 > 为什么我不能在这个函数中返回false,但我可以返回true?(球拍)

问题描述

目标是检查非负数的数字是否按递增顺序排列。

这是我的代码:

(define (in-order-iter num)
  (define (aux num-left result-so-far)
    (cond ((equal? result-so-far #f) #f)
          ((< num-left 10) result-so-far)
          ((aux (quotient num-left 10) (< (modulo (quotient num-left 10) 10)(modulo num-left 10))))))
  (aux num #t))

(in-order-iter 321)

最糟糕的是,当我决定使用 时(display result-so-far),我得到了我想要的答案(即#f),但我的函数不会返回它。如果我决定使用(in-order-iter 123),它会返回#t。当我测试

(< (modulo (quotient 321 10) 10)(modulo 321 10)))

单独,它确实返回#f,所以它应该更改result-so-far#f

为什么会发生在我身上?!

编辑:顺便说一句,我可以递归地执行此功能并且它有效:

(define (in-order-recur num)
  (if (> num 10)
      (if (< (modulo (quotient num 10) 10) (modulo num 10))
            (in-order-recur (quotient num 10))
            #f)
      #t))    

(in-order-recur 100000)

标签: schemeracket

解决方案


您应该使用一个else子句作为最后一个cond术语:

(define (in-order-iter num)
  (define (aux num-left result-so-far)
    (cond ((equal? result-so-far #f) #f)
          ((< num-left 10) result-so-far)
          (else (aux (quotient num-left 10) 
                     (< (modulo (quotient num-left 10) 10)
                        (modulo num-left 10))))))
  (aux num #t))

因此,当您不这样做时,会发生什么#f成为谓词,并且由于它是假的,它将进入下一个术语。由于您没有更多条款,因此由实现决定cond. R6RS 的建议是“未指定的值”。例如。Racket 将导致#<void>默认情况下不打印。实际上,尽管实现可能会执行以下操作:

(define (in-order-iter num)
  (define (aux num-left result-so-far)
    (cond ((equal? result-so-far #f) #f)
          ((< num-left 10) result-so-far)
          ((aux (quotient num-left 10) 
                (< (modulo (quotient num-left 10) 10)
                   (modulo num-left 10))))
          (else "BaNaNa")))
  (aux num #t))

依赖于作为值返回的内容,例如。MIT Scheme 返回一些有用的值,会将您锁定在特定的方言中并且不可移植。

如果该值在基本情况下为真,则默认情况为#t. 然后由于该术语没有结果部分,#t因此返回值。


推荐阅读