了解第一个参数使用翻转时的map函数

时间:2019-06-08 13:24:17

标签: haskell functional-programming higher-order-functions

我正在从“了解Haskell带来的好处!”中学习高阶函数!由Miran Lipovaca撰写。我知道flip函数接受一个函数并返回一个与原始函数类似的函数,但是前两个参数被翻转。

我不完全了解以下带有map函数的示例的工作方式。

ghci> map (flip subtract 20) [1,2,3,4]
[19,18,17,16]

Map接受一个函数并将其应用于列表的每个元素,从而生成一个新列表。但是由于函数map是带参数subtract 20 [1,2,3,4]的flip,因此生成的函数为20 subtract [1,2,3,4]吗?

我认为这是不正确的,因为仅当您键入subtract 1 20时才会生成诸如19之类的值。我不确定在上面的示例中减法将如何工作以产生输出列表。

3 个答案:

答案 0 :(得分:8)

否,这里的功能map :: (a -> b) -> [a] -> [b](flip subtract 20),这是您传递给map的参数。因此,这意味着:

map (flip subtract 20) [1,2,3,4]

等效于:

[flip subtract 20 1, flip subtract 20 2, flip subtract 20 3, flip subtract 20 4]

flip :: (a -> b -> c) -> b -> a -> c是一个接受函数并翻转参数的函数。因此,flip subtract 20在语义上等效于\x -> subtract x 20。因此,我们的列表等效于:

[subtract 1 20, subtract 2 20, subtract 3 20, subtract 4 20]

subtract :: Num a => a -> a -> a(-)的“翻转”版本,因此等效于:

[20 - 1, 20 - 2, 20 - 3, 20 - 4]

因此等同于:

Prelude> map (flip subtract 20) [1,2,3,4]
[19,18,17,16]

因此,上述表达式的缩写是:

map (20 -) [1,2,3,4]

答案 1 :(得分:3)

flip具有以下功能:它以相反的顺序(“翻转”)将给定功能应用于两个给定参数。

Prelude> :t flip
flip :: (a -> b -> c) -> b -> a -> c

这就是(flip subtract 20)变成函数f(x)= 20-x的方式,其中(subtract 20)对应于g(x)= x-20。

然后,使用map函数将f应用于每个列表项。

答案 2 :(得分:3)

  

但是由于翻转是功能映射所需要的...

不。 map将函数作为其第一个参数-这里是flip subtract 20。正如我们现在所看到的,这确实是一个函数(如果不是,则编译器会引发错误,因为它在这里需要一个函数)。

我们将从subtract开始-实际上定义为flip (-)。这意味着flip subtract就是(-),或者:

flip subtract = \a b -> a - b

相对于

subtract = \a b -> b - a

因此,通过进行以下操作:

flip subtract a = \b -> a - b

并替换为20:

flip subtract 20 = \b -> 20 - b

所以flip subtract 20确实是一个函数,它返回从20中减去其参数的结果。map在给定的列表上使用此函数会显示结果。