在 Scheme 中用 "and" 和 "or" 编写程序

Writing procedure with "and" and "or" in Scheme

我正在使用 DrRacket 学习 Scheme,并正在研究一个名为“sign”的过程,它接受一个参数,returns -1 如果它小于 0,1 如果它大于 0,和 0 如果 = 0.

我的代码如下

(define (sign x)
     (and (> x 0) 1)
      (and (= x 0) 0)
       (and (< x 0) -1))

我只能使用'and'和'or'来编写任务中的代码,这意味着我不能使用'if'和'cond'等

我的代码 returns #t,当 运行 它与 (sign 5) 或其他任何东西。

首先,sign 过程已经存在,您正在覆盖它,需要注意的事情。

所以你有这个要求在你的实现中只使用 and, or。嗯,你只是错过了 or 部分 :)

(define (sign x)
  (or
   (and (> x 0) 1)
   (and (= x 0) 0)
   (and (< x 0) -1)))

例如:

(sign -10) ; -1
(sign 100) ;  1
(sign 0)   ;  0

My code returns #t, when runnig it with (sign 5) or anything else.

这不是真的。当参数为负时它将 return -1 否则 #f

想象一下调用 (sign 1),那将:

  • (and (> 1 0) 1) 被评估为 #t,但它的值没有被 return 编辑或保存在任何地方,而是死代码
  • (and (= 1 0) 0) 被评估为 #f,但它的值没有被 return 编辑或保存在任何地方,而是死代码
  • (and (< x 0) -1) 被评估为 #f。由于这是在尾部位置,因此该值是 returned 并且是该过程的结果。

然而这个过程:

(define (add a b)
  (display "adding "
  (display a)
  (display " and "
  (display b)
  (newline)
  (+ a b))

这个有 6 个表达式,它们都在做一些有用的事情,因为前 5 个有打印 "adding <a> and <b>\n" 的副作用,而它们的 returned 值被忽略,最后一个表达式return 是程序的结果。最后一个表达式称为尾表达式。

在创建过程时,您不应该使用一个以上的表达式来完成工作,除非设计使用了副作用。例如。你的 3 不能分开。您需要将它们结合起来的逻辑。由于错误值是 #f,但每个结果都是一个数字并且始终被认为是正确的,因此您可以将这 3 个放在 or:

(define (my-sign x)
  (or (and (> x 0) 1)
      (and (= x 0) 0)
      (and (< x 0) -1)))

当调用 (my-sign 1) 时,(> x 0) 将是 #t,其中 1 被评估,第一个 and 表达式的结果,因为 or 将在第一个真值处停止,结果变为 1。另请注意,不需要最后一个表达式,因为我们知道如果它不高于或等于零,则它必须低于零。因此最后的 and 表达式可以替换为 -1:

(define (my-sign x)
  (or (and (> x 0) 1)
      (and (= x 0) 0)
      -1)) ; if not equal or higher than 0 it has to be negative!