我想将 or
应用于列表的每个元素,示例: (apply or '(#t #t #f))
预期结果#t
,但我遇到了错误:
'#'to'apply'的类型错误(kawa.lang.macro)(预期:过程,序列或其他操作员)
我知道or
不是一个过程。是否可以使用任何可以使用的过程代替or
?
最简单的方法是使用exists
*。每当您使用(apply or some-list)
时,都可以使用(exists values some-list)
。或者,如果您愿意,可以定义使用exists
来执行此操作的函数:
#!r6rs
(import (rnrs base)
(rnrs lists))
(define (or* . lst)
(exists values lst))
values
是身份函数,因此(values x)
只是x
。
exists
是定义的高阶函数,因此(exists f (list x ...))
等于(or (f x) ...)
。
例如,(exists values (list #t #t #f))
等于(or (values #t) (values #t) (values #f))
,与(or #t #t #f)
相同。
尝试一下:
> (apply or* '(#t #t #f))
#t
> (apply or* '(#f #f #f))
#f
> (or* #t #t #f)
#t
> (or*)
#f
* exists
有时被称为ormap
或any
在srfi-1列表库中,您的every
和any
基本上是and
和or
,对于列表上的过程。
#!r6rs
(import (rnrs base)
(only (srfi :1) every any)
(define num1-10 '(1 2 3 4 5 6 7 8 9 10))
(define odd1-9 '(1 3 5 7 9))
(every odd? num1-10) ; ==> #f
(any odd? num1-10) ; ==> #t
(every odd? odd1-9) ; ==> #t
对于布尔值列表,该过程只需要返回参数即可。values
返回其参数并用作身份:
(define booleans '(#f #t))
(every values booleans) ; ==> #f
(any values booleans) ; ==> #t
srfi-1是一个安全的选择,因为它是即将推出的R7RS红色版本的列表库。在许多R5RS和R6RS实现中包括SRFI-1,如果不是,您可以轻松地从SRFI参考实现中添加它。在具有ormap
和andmap
的Drracket的默认语言Drracket中,您可以选择使用SRFI-1而不是通过使用(require srfi/1)
导入SRFI-1。
您可以定义自己的过程或
(define (orp . ls)
(if (null? ls) #f
(if (< (length ls) 2) (car ls) (or (car ls) (orp (cdr ls))))))
并使用它:
(apply orp '(#t #f #t))
要点是or
(和if
,cond
,and
....)操作员具有懒惰的评估语义。因此,(or #t (/ 1 0))
不会零划分。因此,or
不能是普通的功能。
您可能会编码lambda来迫使急切的评估,例如定义您的eager-or
variadic函数,并应用。