我正在使用Racket和Dr. Racket。
有一个名为andmap的内置函数。
andmap的内置版本以这种方式工作:
> (andmap positive? '(1 2 3))
#t
功能编号通常用作:
(number? 3)
> #t
(number? '())
>#f
我不明白为什么会这样:
(andmap number? '())
> #t
我认为结果应该是假的。
文档说:
*If the lsts are empty, then #t is returned.*
为什么这有意义呢?我没看到。我很好奇语言的设计选择,特别是新的语言,如Racket。
答案 0 :(得分:7)
(andmap pred '())
返回#t
的原因与(and)
返回#t
的原因完全相同......但这可能不是最有用的解释,是吗?真正的答案是#t
是逻辑AND的标识,就像0是加法标识,1是乘法标识:
> (+)
0
> (*)
1
> (and)
#t
> (or)
#f
这里的想法是,当与任何给定输入结合时,身份不会改变输出。例如,就像(+ 0 x)
始终为x
而(* 1 x)
始终为x
,(and #t x)
始终为x
且(or #f x)
为总是x
。这是一个有用的属性,因为它与用于求和Scheme中的列表的惯用方法很好地合作,(apply + lst)
:
> (apply + '(1 2 3))
6
> (apply + '())
0
同样,可以使用(apply * lst)
代替单独的product
函数。 and
和or
运算符不能与apply
一起使用,因为它们是短路的,因此实现为宏而不是函数,但是andmap
和{{1}而是实现该功能。
如果这个论点对你来说似乎不够令人满意,你也可以用简单的英语定义来思考这些事情,得出相同的结论。 ormap
操作意味着是什么意思?好吧,它问了一个问题:“这个列表中的所有元素是否都满足谓词?”在空列表中,答案总是是,因为你不可能产生一个反例。权利要求。
相比之下,andmap
是双重的:“这个列表中至少有一个元素是否满足谓词?”答案总是不,因为它不可能产生任何元素,所以产生一个满足谓词的元素肯定是不可能的。