为什么以下不起作用?
(apply and (list #t #t #f))
虽然以下方法效果很好。
(apply + (list 1 3 2))
R5RS和R6RS似乎都是这样?
and
不是一个普通函数,因为它只会计算所需的尽可能少的参数,以了解结果是真还是假。例如,如果第一个参数为 false,则无论其他参数是什么,结果都必须为 false,因此它不会评估其他参数。如果 and
是普通函数,则将首先评估其所有参数,因此 and
被设为特殊关键字,这就是它不能作为变量传递的原因。
(define and-l (lambda x
(if (null? x)
#t
(if (car x) (apply and-l (cdr x)) #f))))
请注意,这是 lambda variadic! 应用示例
(and-l #t #t #f)
或者您可以通过申请程序使用它(按照要求) 例如
(apply and-l (list #t #t #f))
两个选项都可以...
and
实际上是一个宏,其定义在R5RS第4章中有概述。该页面上的“库语法”符号实际上意味着它是作为宏实现的。
第 7.3 节,派生表达式类型 给出了 and
宏的可能定义:
(define-syntax and
(syntax-rules ()
((and) #t)
((and test) test)
((and test1 test2 ...)
(if test1 (and test2 ...) #f))))
鉴于此定义,不可能使用
and
作为
apply
的函数参数。
MIT/GNUScheme中,您可以使用函数boolean/and
and
。
(apply boolean/and (list #t #t #f)) ;Value: #f
此外,郑重声明,我在 Guile Scheme 的 过程索引中找不到任何等效函数。
(其他答案已经解释了为什么特殊形式and
不起作用,并展示了如果您的方言中还没有这样的函数,如何编写自己的替换函数。)
(define and-l (lambda (a b) (and a b)))
您可以这样申请:
(apply and-l (list #t #f))
两个注意事项是:
that中的一个函数语言。所以我想出了以下解决方案,我只需将惰性和导入为“惰性与”:
#lang racket
(require (only-in lazy [and lazy-and]))
(define (mm)
(map number? '(1 2 3)))
(printf "~a -> ~a\n" (mm) (apply lazy-and (mm)))
产生
(#t #t #t) -> #t
(define list-and (lambda (args) (and (car args) (list-and (cdr args)))))
然后你可以使用 apply to list-and!
(define (andApply lBoo)
(if (not (car lBoo)) #f
(if (= 1(length lBoo)) (car lBoo)
(andApply (cdr lBoo)))))
(apply and lst)
返回一样,但我还没有'没有进行详尽的测试。
(define (list-and lst)
(cond
((null? lst) '())
((not (pair? lst)) (and lst))
((eq? (length lst) 1) (car lst))
(else
(and (car lst)
(list-and (cdr lst))))
)
)
Welcome to DrScheme, version 372 [3m].
Language: Textual (MzScheme, includes R5RS).
> (eq? (and '()) (list-and '()))
#t
> (eq? (and '#f) (list-and (list '#f)))
#t
> (eq? (and 'a) (list-and (list 'a)))
#t
> (eq? (and 'a 'b) (list-and (list 'a 'b)))
#t
> (eq? (and 'a 'b '()) (list-and (list 'a 'b '())))
#t
> (eq? (and 'a 'b '#t) (list-and (list 'a 'b '#t)))
#t
> (eq? (and 'a 'b '#f) (list-and (list 'a 'b '#f)))
#t
我还想出了另一个“思维陷阱”解决方法。我称它为
思维陷阱,因为一开始我不知道如何将它变成一个函数......这就是(只是我直观想法的演示):
Welcome to DrScheme, version 372 [3m].
Language: Textual (MzScheme, includes R5RS).
> (eval (cons 'and (list ''#f ''#f ''#t)))
#f
> (eval (cons 'and (list ''a ''b ''c)))
c
是否可以动态生成 (quote (quote var)) 或 ''var?。有了这个答案,我们就可以轻松地将上述想法转化为函数。