我在racket和MIT计划中尝试使用以下代码,让我惊讶的是编译器抛出错误
(foldr and #t '(#t #t #f))
有没有办法使用reduce / fold方式检查列表是仅包含true还是false? 我知道lambda可以完成这项工作,但它确实让我们想知道为什么这不是一个有效的代码。 我记得我可以在哈斯克尔做到这一点......
TIA。
答案 0 :(得分:8)
and
是一个宏,因此它本身没有值。具体来说,它会短路评估,并且在您尝试使用它时没有任何意义。出于这个原因,Racket有andmap
,你可以在这种情况下使用它。 (其他实现在不同的名称下具有类似的功能 - 例如,srfi-1使用every
。)
答案 1 :(得分:7)
并且是一个宏,不能用作函数。把它放在一个函数中:
(foldr (lambda (a b) (and a b)) #t '(#t #t #f))
答案 2 :(得分:1)
这适用于诡计:
(primitive-eval (cons 'and '(#t #f)))
答案 3 :(得分:1)
可能有一件事是在Racket和Scheme中,真正的值不是#f。由于你的问题要求布尔值,以下将更具辨别力:
#lang racket
(define (boolean-true? x) (eq? x #t))
(define (only-contains-#t? l)
(andmap boolean-true? l))
例如,
> (only-contains-#t? '())
#t
> (only-contains-#t? '(#t #t #t))
#t
> (only-contains-#t? '(#t #t true))
#f