Scheme 如何使用和/或代替if/cond?

Scheme 如何使用和/或代替if/cond?,scheme,lisp,r5rs,Scheme,Lisp,R5rs,我是Scheme编程的新手,我已经完成了这个任务,我就是不知道如何正确地工作。我应该用一个参数(一个数字)定义一个过程。如果数字为正数,我希望返回1,如果数字为负数,则返回-1,如果数字为0,则返回0,仅使用和/或。If和cond是不允许的。我只得到#t或#f返回,但你看,这不是我想要的。感谢您的帮助或指点(定义测试 (define test (lambda (n) (or (and (< n 0) -1) (and (= n 0) 0)

我是Scheme编程的新手,我已经完成了这个任务,我就是不知道如何正确地工作。我应该用一个参数(一个数字)定义一个过程。如果数字为正数,我希望返回
1
,如果数字为负数,则返回
-1
,如果数字为0,则返回
0
,仅使用和/或。If和cond是不允许的。我只得到#t#f返回,但你看,这不是我想要的。感谢您的帮助或指点

(定义测试
(define test 
    (lambda (n)
        (or (and (< n 0) -1)
            (and (= n 0) 0)
            1)))
(λ(n) (或(和(

技巧的一部分是理解,如果所有的计算结果都为true,那么and将返回它计算的最后一项,而or将返回成功计算的第一项为true。另一部分是认识到除了#f之外的所有东西都被认为是“真实的”。

报告中看到了
的转换,但不包括实际的宏,基本上是这样的:

;只有一个论点
(和a);==>
A.
; 其中一个
(和a b…)==>
(如属
(和b…)
#(f)
所有参数都必须计算为正值,最后一个值是结果,否则
#f
。它会短路,因此当某个表达式是
#f
时,其余的表达式永远不会被计算

对于
,如下所示:

(或a);=>
A.
(或a b…)==>
(let((a值a))
(如果是a值
a值
(或b…)
返回计算结果不为
#f
的第一个参数。如果所有值均为
#f
,则最后一个
#f
将作为结果

因此,如果您想要:

(如果a b c);=>
(让((tmpa a))
(或)(及b)
(和(不是atmpa)c));如果b可以是#f,则不是唯一重要的部分
我使用
let
来防止多次计算同一个表达式。例如,如果有一个表达式打印了类似
(begin(display“hello”)#f)
的内容,或者这是一个昂贵的计算,那么这是必要的,否则您可以用表达式替换变量。例如,最后一个表达式将变成:

(或(和a b)
(及(非a)c)
在没有临时变量的情况下转换回的将成为:

(如果(如果是b#f)
(如果是b#f)
(如果(不是a)c#f))
如果b是
#f
值,那么结果是
#f
,因为最后一个
If
。因此每次
a
都是真的
b
就是结果。每次它是假的时候,
c
就是答案。因此

(如果是a b c)
因此,假设您想要返回列表中的第一个真值

(定义(第一个真正的lst)
(和(非(空?lst))
(车辆lst)
(第一个为真(cdr lst)))

如果查看以下等价项,您可以解决问题,当每个
expj
的值不同于
#f
时有效:

(cond (test1 exp1)         (or (and test1 exp1)
      (test2 exp2)             (and test2 exp2)
      ...               ≡      ...
      (testn expn)             (and testn expn)
      (else expn+1))           expn+1)
由于获取数字符号的函数可以简单地用以下方式编写:

(define (sign x)
  (cond ((> x 0) +1)
        ((< x 0) -1)
        (else 0)))

那么,上述等价性的原因是什么呢?这取决于
依次计算其参数的事实;只要其中一个参数是
#f
,它就停止返回
#f
,否则返回其最后一个参数(这解释了单分支
(和testj expj)
);当
依次计算其参数时;只要其中一个参数不是
#f
,它就停止返回,否则返回其最后一个参数(这解释了链
(或(和…(和…)expn+1)
)。

只有当所有的expn都为真时,这种等价关系才是正确的。显示您的代码。到目前为止您尝试了什么?
(define (sign x)
  (or (and (> x 0) +1)
      (and (< x 0) -1)
      0))