我正在寻找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)
你能解决它还是指向内置功能?(我用谷歌搜索,但没有得到有意义的结果)
你已经接受了另一个解释一个很好的方法的答案,但我认为值得指出你的尝试出了什么问题,因为它实际上非常接近.问题是从when块完全忽略了.它不会导致函数返回.因此,即使您有空列表,也可以评估时间,然后继续进入您使用相同的空列表调用car和cdr的另一部分:
(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)
你实际上在开始时非常接近.
如果您正在寻找内置解决方案,您可能需要查看一下andmap,它将谓词应用于整个列表并将and结果放在一起.
您可以使用它来all非常简单地实现.
(define (all lst)
(andmap identity lst))
Run Code Online (Sandbox Code Playgroud)
通过使用identityfrom racket/function,all将只使用列表中的值.identity您也可以使用values,而不是显式使用,这只是单个值上的标识函数,因此它在Racket中是一种常见的习惯用法.