为什么andmap会在这种情况下返回#t?

2 lisp racket

我正在使用Racket和Dr. Racket.

有一个名为andmap的内置函数.

内置版本的andmap以这种方式工作:

> (andmap positive? '(1 2 3))

#t
Run Code Online (Sandbox Code Playgroud)

功能号通常用作:

(number? 3)
> #t

(number? '())
>#f
Run Code Online (Sandbox Code Playgroud)

我不明白为什么会这样:

(andmap number? '())

> #t
Run Code Online (Sandbox Code Playgroud)

我认为结果应该是假的.

文件说:

*If the lsts are empty, then #t is returned.*
Run Code Online (Sandbox Code Playgroud)

为什么这有意义呢?我没看到.我很好奇语言的设计选择,特别是新的语言,如Racket.

Ale*_*ing 7

理由(andmap pred '())退货#t是完全一样的道理(and)回报#t......但是这也许不是最有用的解释,是吗?真正的答案是逻辑AND #t标识,就像0是加法标识,1是乘法标识:

> (+)
0
> (*)
1
> (and)
#t
> (or)
#f
Run Code Online (Sandbox Code Playgroud)

这里的想法是,当与任何给定输入组合时,标识不会改变输出.举例来说,就像(+ 0 x)是始终x(* 1 x)永远x,(and #t x)永远是x(or #f x)永远x.这是一个有用的属性,因为它与用于汇总Scheme中列表的惯用方法很好地协作(apply + lst):

> (apply + '(1 2 3))
6
> (apply + '())
0
Run Code Online (Sandbox Code Playgroud)

同样,(apply * lst)可以使用代替单独的product功能.在andor运营商不能使用apply,因为它们是短路,并且因此被实现为宏,而不是功能,而是andmapormap实现该功能来代替.


如果这个论点对你来说似乎不够令人满意,你也可以用他们简单的英语定义来思考这些事情,得出相同的结论.这个andmap操作意味着什么?好吧,它提出一个问题:"这个列表中的所有元素是否都满足谓词?"在空列表中,答案将始终为,因为您不可能对该声明产生反例.

相比之下,ormap是双重的:"这个列表中至少有一个元素是否满足谓词?"答案总是不行,因为根本不可能产生任何元素,所以产生一个满足谓词的元素肯定是不可能的.