All:当且仅当列表的所有元素都为真时,函数才返回真

All: A Function Returning True if and only if All Elements of a List are True

我正在寻找 Racket 中的内置函数,它将 return 为真,前提是列表中的所有项目都为真。

我试过了:

(define (all lst)
  (when 
      (equal? lst '()) 
      #t)
  (if (not (car lst))
      #f
      (all (cdr lst))))

给出错误:

car: contract violation
  expected: pair?
  given: '()

几个测试用例:

(all '(#t #f #t)) ; #f
(all '(#t #t #t)) ; #t

能否请您修复它或指出内置函数? (我googled,但没有得到有意义的结果)

有两种列表:空列表和对列表。

因此我们有如下结构:

(define (all xs)
  (cond
    [(empty? xs) ...]
    [(pair?  xs) ...]
    [else        (error 'all "expected a list, got: " xs)]))

由于空列表中的所有元素都为真,我们得到:

(define (all xs)
  (cond
    [(empty? xs) #t]
    [(pair?  xs) ...]
    [else        (error 'all "expected a list, got: " xs)]))

如果列表以一对开始,则列表的所有元素都为真, 如果列表的第一个元素和列表的其余元素都为真:

(define (all xs)
  (cond
    [(empty? xs) #t]
    [(pair?  xs) (and (first xs) (all (rest xs)))]
    [else        (error 'all "expected a list, got: " xs)]))

请注意,您程序中的部分问题是使用 when

结果

(when #t
   'foo)
'bar

'bar。构造 when 仅在您使用副作用(例如由 set! 和朋友引起)时才有用。

您已经接受了另一个解释执行此操作的好方法的答案,但我认为有必要指出您尝试中的错误之处,因为它实际上非常接近。问题是 when 块中的 true 被完全忽略了。它不会导致函数 return。因此,即使您有空列表,您也会在 时评估 ,然后 继续 进入您调用 [=22= 的另一部分]carcdr 具有相同的空列表:

(define (all lst)
  (when                  ;  The whole (when ...) expression
      (equal? lst '())   ;  is evaluated, and then its result
      #t)                ;  is ignored.
  (if (not (car lst))   
      #f
      (all (cdr lst))))

一个非常快速的解决方案是将其更改为:

(define (all lst)
  (if (equal? lst '())  
      #t               
      (if (not (car lst))   
          #f
          (all (cdr lst)))))

到那时,您可以使用布尔运算符来简化一点,而不是 return 显式地确定 true 和 false,并使用 empty?[=27 稍微清理一下=],如另一个答案中所述:

(define (all lst)
  (or (empty? lst)  
      (and (car lst)
           (all (cdr lst)))))

你们一开始其实很接近。

如果您正在寻找内置解决方案,您可能想看看 andmap,它对整个列表应用谓词并将结果 and 放在一起。

您可以使用它非常简单地实现 all

(define (all lst)
  (andmap identity lst))

通过使用 racket/function 中的 identityall 将按原样使用列表中的值。除了显式使用 identity,您还可以使用 values,这只是单个值的恒等函数,所以它在 Racket 中有点常见。

All 是一个 higher order folding function. Scheme refers to these as "reductions" and reduce is available in SRFI-1

Gauche方案中:

(use srfi-1)
(define (all list-of-x)
  (reduce (lambda (x y) 
            (and x y))
          #t
          list-of-x))

将 return #f 或计算结果为 true 的值。例如:

gosh> (all '(1 2 3))
1

如果没问题,那么我们就完成了。否则我们总能得到 #t 与:

(use srfi-1)
(define (all-2 list-of-x)
  (if (reduce (lambda (x y)
        (and x y))
          #t
          list-of-x)
      #t
      #f))

然后结束:

gosh> (all '(1 2 3))
#t