全部:当且仅当列表的所有元素都为True时,返回True的函数

Car*_*orc 1 scheme racket

我正在寻找Racket中的内置函数,如果列表中的所有项都为真,则返回True.

我试过了:

(define (all lst)
  (when 
      (equal? lst '()) 
      #t)
  (if (not (car lst))
      #f
      (all (cdr lst))))
Run Code Online (Sandbox Code Playgroud)

给出错误:

car: contract violation
  expected: pair?
  given: '()
Run Code Online (Sandbox Code Playgroud)

几个测试用例:

(all '(#t #f #t)) ; #f
(all '(#t #t #t)) ; #t
Run Code Online (Sandbox Code Playgroud)

你能解决它还是指向内置功能?(我用谷歌搜索,但没有得到有意义的结果)

Jos*_*lor 5

你已经接受了另一个解释一个很好的方法的答案,但我认为值得指出你的尝试出了什么问题,因为它实际上非常接近.问题是从when块完全忽略了.它不会导致函数返回.因此,即使您有空列表,也可以评估时间,然后继续进入您使用相同的空列表调用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))))
Run Code Online (Sandbox Code Playgroud)

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

(define (all lst)
  (if (equal? lst '())  
      #t               
      (if (not (car lst))   
          #f
          (all (cdr lst)))))
Run Code Online (Sandbox Code Playgroud)

那时,您可以通过使用布尔运算符而不是显式返回true和false来简化一点,并通过使用空来清理一点,如另一个答案所述:

(define (all lst)
  (or (empty? lst)  
      (and (car lst)
           (all (cdr lst)))))
Run Code Online (Sandbox Code Playgroud)

你实际上在开始时非常接近.


Ale*_*ing 5

如果您正在寻找内置解决方案,您可能需要查看一下andmap,它将谓词应用于整个列表并将and结果放在一起.

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

(define (all lst)
  (andmap identity lst))
Run Code Online (Sandbox Code Playgroud)

通过使用identityfrom racket/function,all将只使用列表中的值.identity您也可以使用values,而不是显式使用,这只是单个值上的标识函数,因此它在Racket中是一种常见的习惯用法.