【发布时间】:2018-02-06 12:35:40
【问题描述】:
j :: [Int]
j = filter ((\h x -> h x > x) (\y -> y*y)) [-2,-1,0,1,2]
这个输出[-2,-1,2] 但是为什么呢?有人可以逐步解释一下 Haskell 在这里做了什么来得到这个输出吗?
【问题讨论】:
j :: [Int]
j = filter ((\h x -> h x > x) (\y -> y*y)) [-2,-1,0,1,2]
这个输出[-2,-1,2] 但是为什么呢?有人可以逐步解释一下 Haskell 在这里做了什么来得到这个输出吗?
【问题讨论】:
它通过谓词过滤函数([-2, -1, 0, 1, 2])中的列表,谓词是表达式((\h x -> h x > x) (\y -> y*y))。
我们在这里看到两个 lambda 表达式。前者将h和x两个参数作为输入,如果h x大于x,则返回True。第二个将参数y 作为输入,并返回y*y(因此它平方输入)。
第二个 lambda 表达式作为第一个 lambda 表达式的第一个参数,也就是说:
((\h x -> h x > x) (\y -> y*y))
-----------------------------------
= \x -> (\y -> y*y) x > x
因此,当且仅当(\y -> y*y) x 大于x 时,函数将变量x 作为输入并返回True。我们可以再次通过以下方式进一步简化该函数:
\x -> (\y -> y*y) x > x
-------------------------
= \x -> x*x > x
因此,它是一个谓词,用于检查给定 x 是否为 x*x > x,或者“变量应小于该变量的平方”。
所以我们在这里过滤列表[-2, -1, 0, 1, 2],以便只保留其平方较大的元素。因此,如果我们对此进行评估,我们会看到:
x|x*x|x*x > x
---+---+-------
-2| 4| True
-1| 1| True
0| 0| False
1| 1| False
2| 4| True
所以结果是[-2, -1, 2]。
【讨论】:
(\h x -> h x > x) (\y -> y*y)
等价于
\x -> x*x > x
因此,您只需对列表中的每个数字进行平方,并将其与原始数字进行比较,即可了解输出为何如此:
-- original: [-2, -1, 0, 1, 2]
-- squared: [ 4, 1, 0, 1, 4]
-- comparison: [ T, T, F, F, T]
此谓词将为每个负数返回 True(因为每个负数的平方都是正数,因此大于原始数,并且对于每个大于 1 的正数。由于您在 Ints 上进行操作,这意味着 0 和 1 是唯一会导致该谓词失败的数字。
【讨论】: