我正在使用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.
理由(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功能.在and与or运营商不能使用apply,因为它们是短路,并且因此被实现为宏,而不是功能,而是andmap和ormap实现该功能来代替.
如果这个论点对你来说似乎不够令人满意,你也可以用他们简单的英语定义来思考这些事情,得出相同的结论.这个andmap操作意味着什么?好吧,它提出一个问题:"这个列表中的所有元素是否都满足谓词?"在空列表中,答案将始终为是,因为您不可能对该声明产生反例.
相比之下,ormap是双重的:"这个列表中至少有一个元素是否满足谓词?"答案总是不行,因为根本不可能产生任何元素,所以产生一个满足谓词的元素肯定是不可能的.