定义 lambda 演算构造函数的正确方法
Right way to define lambda-calculus constructors
是否有明确的方法可以在 lambda 演算中查找项?例如假设我们有一对构造函数
pair = λa. λb. λf. f a b
我们有 fst
构造函数
fst = λp. p (λa. λb. a)
即 returns 对的第一个元素,我们现在必须定义 snd
构造函数,其中 returns 对的第二个元素。我已经到了这样定义它
snd = λp. p (λa. λb. b)
与 snd (pair a b) = b
。
snd 也可以定义为
snd = λp. p (λb. λa. b)
,
问题是,是否有明确的方法来定义新的构造函数?
当我必须定义构造函数时,人们应该如何思考,当我被要求定义新的构造函数时,我如何测试我的答案是否正确。
(λa. (λb. b)) x y = (λb. b) y = y
但是
(λb. (λa. b)) x y = (λa. x) y = x
,所以不,两者不等价:第一个定义 returns 它的 第二个 参数,但第二个定义 returns 它的 第一个个参数。
名称不算数,除非与参数建立对应关系。参数的 位置 计数。
至于如何思考,我经常发现以 组合 风格写下定义更容易理解:
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 pair of a
and b
will, given a selector procedure, feed it a
first, and b
, second."等
我们可以通过简单的语法转换在两种风格之间来回切换,例如:
second_argument_selector a b = b =>
second_argument_selector a = (λb . b) =>
second_argument_selector = (λa . (λb . b))
如意算盘的原则往往很有帮助:我们使用一些功能就好像它们已经写好了;然后它们的用途决定了我们必须如何定义它们。就像我们在上面对 first_argument_selector
和 second_argument_selector
所做的那样。
好名字有帮助。视觉对齐代码会有所帮助。此外,使用完整的括号(就像我在 post 的顶部所做的那样)。
是否有明确的方法可以在 lambda 演算中查找项?例如假设我们有一对构造函数
pair = λa. λb. λf. f a b
我们有 fst
构造函数
fst = λp. p (λa. λb. a)
即 returns 对的第一个元素,我们现在必须定义 snd
构造函数,其中 returns 对的第二个元素。我已经到了这样定义它
snd = λp. p (λa. λb. b)
与 snd (pair a b) = b
。
snd 也可以定义为
snd = λp. p (λb. λa. b)
,
问题是,是否有明确的方法来定义新的构造函数?
当我必须定义构造函数时,人们应该如何思考,当我被要求定义新的构造函数时,我如何测试我的答案是否正确。
(λa. (λb. b)) x y = (λb. b) y = y
但是
(λb. (λa. b)) x y = (λa. x) y = x
,所以不,两者不等价:第一个定义 returns 它的 第二个 参数,但第二个定义 returns 它的 第一个个参数。
名称不算数,除非与参数建立对应关系。参数的 位置 计数。
至于如何思考,我经常发现以 组合 风格写下定义更容易理解:
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 pair of a
and b
will, given a selector procedure, feed it a
first, and b
, second."等
我们可以通过简单的语法转换在两种风格之间来回切换,例如:
second_argument_selector a b = b =>
second_argument_selector a = (λb . b) =>
second_argument_selector = (λa . (λb . b))
如意算盘的原则往往很有帮助:我们使用一些功能就好像它们已经写好了;然后它们的用途决定了我们必须如何定义它们。就像我们在上面对 first_argument_selector
和 second_argument_selector
所做的那样。
好名字有帮助。视觉对齐代码会有所帮助。此外,使用完整的括号(就像我在 post 的顶部所做的那样)。