用filter和lambda表达式理解Haskell函数

Luk*_*eln -3 haskell list filter

j :: [Int]
j = filter ((\h x -> h x > x) (\y -> y*y)) [-2,-1,0,1,2]
Run Code Online (Sandbox Code Playgroud)

这个输出[-2,-1,2]但为什么?有人可以一步一步地向我解释Haskell在这里做什么来获得这个输出?

Bar*_*icz 5

(\h x -> h x > x) (\y -> y*y)
Run Code Online (Sandbox Code Playgroud)

相当于

\x -> x*x > x
Run Code Online (Sandbox Code Playgroud)

所以你只需要对列表中的每个数字进行平方并将其与原始数字进行比较,看看为什么输出是这样的:

-- original:   [-2, -1,  0,  1,  2]
-- squared:    [ 4,  1,  0,  1,  4]
-- comparison: [ T,  T,  F,  F,  T]
Run Code Online (Sandbox Code Playgroud)

这个谓词将返回True每个负数(因为每个负数的平方都是正数,因此大于原数,并且对于每个大于1的正数.因为你在Ints上运算,这意味着0并且1是唯一的数字会失败那个谓词.


Wil*_*sem 5

[-2, -1, 0, 1, 2]通过谓词过滤函数 ( ) 中的列表,谓词是表达式((\h x -> h x > x) (\y -> y*y))

我们在这里看到两个lambda 表达式。前者将两个参数h和作为输入xTrue如果h x大于则返回x。第二个将参数作为输入y,并返回y*y(因此它对输入进行平方)。

第二个 lambda 表达式被作为第一个 lambda 表达式的第一个参数,所以这意味着:

  ((\h x -> h x > x) (\y -> y*y))
-----------------------------------
= \x -> (\y -> y*y) x > x
Run Code Online (Sandbox Code Playgroud)

因此,一个将变量作为输入xTrue在且仅当(\y -> y*y) x大于 时返回的函数x。我们可以再次通过以下方式进一步减少该功能:

  \x -> (\y -> y*y) x > x
-------------------------
= \x -> x*x > x
Run Code Online (Sandbox Code Playgroud)

因此,它是一个谓词,用于检查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  
Run Code Online (Sandbox Code Playgroud)

所以结果是[-2, -1, 2]