在Scheme中使用 AND 和 apply 函数
为什么以下不起作用?
(apply and (list #t #t #f))
虽然以下效果很好。
(apply + (list 1 3 2))
R5RS和R6RS好像都是这样?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
为什么以下不起作用?
(apply and (list #t #t #f))
虽然以下效果很好。
(apply + (list 1 3 2))
R5RS和R6RS好像都是这样?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(9)
and
不是一个普通函数,因为它只会计算所需的尽可能少的参数,以了解结果是 true 还是 false。 例如,如果第一个参数为 false,则无论其他参数是什么,结果都必须为 false,因此它不会评估其他参数。 如果and
是一个普通函数,那么它的所有参数都会首先被求值,因此and
被设为一个特殊的关键字,这就是为什么它不能作为变量传递的原因。and
isn't a normal function because it will only evaluate as few arguments as it needs, to know whether the result is true or false. For example, if the first argument is false, then no matter what the other arguments are, the result has to be false so it won't evaluate the other arguments. Ifand
were a normal function, all of its arguments would be evaluated first, soand
was made a special keyword which is why it cannot be passed as a variable.请注意,这是 lambda 可变参数!
应用示例
(and-l #t #t #f)
或者您可以通过应用程序使用它(按照要求)
例如
(apply and-l (list #t #t #f))
两个选项都可以...
pleas notice that this is lambda variadic!
apply example
(and-l #t #t #f)
or you can use it via apply procedure(as was asked)
for example
(apply and-l (list #t #t #f))
both options are ok...
and
实际上是一个宏,其定义概述为 R5RS 第 4 章。 该页面上的符号“库语法”实际上意味着它是作为宏实现的。7.3 节,派生表达式类型 给出了
and
宏的可能定义:根据此定义,不可能将
and
用作apply
的函数参数。and
is actually a macro, whose definition is outlined in R5RS chapter 4. The notation "library syntax" on that page really means it is implemented as a macro.Section 7.3, Derived expression types gives a possible definition of the
and
macro:Given this defintion, it is not possible to use
and
as a function argument toapply
.在Scheme方言MIT/GNU Scheme中,您可以使用函数
boolean/and< /code>
而不是 特殊形式
和
。另外,根据记录,我在 Guile Scheme 中找不到任何等效的函数过程索引。
(其他答案已经解释了为什么特殊形式
and
不起作用,并展示了如果您的方言中还没有这样的函数,如何编写您自己的替换函数。)In the Scheme dialect MIT/GNU Scheme, you can use the function
boolean/and
instead of the special formand
.Also, for the record, I couldn’t find any equivalent function in Guile Scheme’s procedure index.
(Other answers have already explained why the special form
and
won’t work, and shown how to write your own replacement function if there isn’t already such a function in your dialect.)如果您真的想要一个函数指针指向一个执行 and 的函数,并且您不介意与“真实”and 不同的行为,那么这会起作用:
您可以这样应用:
两个警告是:
If you REALLY wanted to have a function pointer to a function that does and, and you don't mind behavior different than the "real" and, then this would work:
Which you can apply like this:
The two caveats are:
我偶然发现了同样的问题,并在 Racket 中找到了一个优雅的解决方案。
由于问题是“and”是一个宏而不是一个函数,以防止对其所有参数进行求值,所以我读了一些有关“lazyracket”的内容,发现“and”是 中的一个函数那种语言。 所以我想出了以下解决方案,我只需将lazy and导入为“lazy-and”:
这会产生
I've stumbled across the same problem and found an elegant solution in Racket.
Since the problem is that "and" is a macro and not a function in order to prevent the evaluation of all its arguments, I've read a little on "lazy racket" and found that "and" is a function in that language. So I came up with the following solution where I just import the lazy and as "lazy-and":
which yields
试试这个:
然后你可以使用 apply to list-and!
try this:
then you can use apply to list-and!
您还可以使用
(define (andApply lBoo)
(如果(不是(汽车 lBoo))#f
(if (= 1(长度 lBoo)) (车 lBoo)
(andApply (cdr lBoo)))))
You could also use
(define (andApply lBoo)
(if (not (car lBoo)) #f
(if (= 1(length lBoo)) (car lBoo)
(andApply (cdr lBoo)))))
我在玩 PLT-Scheme 372 时也遇到了这个问题,我深入研究了 and 语法的行为,并找出了下面的代码,它的工作原理就像人们直观地期望
(apply and lst)
返回,但我还没有做过详尽的测试。我还想出了另一个思维陷阱解决方法。 我称它为思维陷阱,因为一开始我不知道如何将它变成一个函数......这是(只是我直观想法的演示):
但后来我问了一个问题并在这里得到答案: 是否可以动态生成 (quote (quote var)) 或 ''var? 。 有了这个答案,我们就可以轻松地将上述想法转化为函数。
I also bump into this problem playing with PLT-Scheme 372, I have digged into the behavior of and-syntax, and figure out the follow code which works just as if one would intuitively expect
(apply and lst)
to return, but I haven't done exaustive test.I've also figured out another mind-trapping workaround. I call it mind-trapping because at first I don't know how to turn it into a function... Here it is (only a demo of my intuitive idea):
But later I asked a question and got the answer here: Is it possible to generate (quote (quote var)) or ''var dynamically? . With this answer one can easily turn the above idea into a function.