(λa. (λb. b)) x y = (λb. b) y = y
但
(λb. (λa. b)) x y = (λa. x) y = x
,所以不,两者不等价:第一个定义返回它的第二个参数,但第二个定义返回它的第一个参数。
除了与参数建立对应关系外,名称不算数。参数的位置很重要。
至于如何思考,我经常发现以组合方式写下定义更容易理解:
pair a b selector = selector a b
fst apair = apair first_argument_selector
snd apair = apair second_argument_selector
first_argument_selector a b = a
second_argument_selector a b = b
我认为这很清楚。“给定一个选择器程序,一对a
and将首先输入它,然后再输入它。” b
a
b
等等
我们可以通过简单的句法转换在两种风格之间来回切换,例如:
second_argument_selector a b = b =>
second_argument_selector a = (λb . b) =>
second_argument_selector = (λa . (λb . b))
一厢情愿的原则通常很有帮助:我们使用一些函数,就好像它们已经编写好了;那么它们的用途决定了我们必须如何定义它们。就像我们对上面的first_argument_selector
and所做的那样second_argument_selector
。
好名字有帮助。视觉上对齐代码会有所帮助。此外,使用完整的括号(就像我在帖子顶部所做的那样)。