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

cen*_*980 4 haskell functional-programming higher-order-functions

我正在从“了解Haskell来取得良好成就!”中学习高阶函数!由Miran Lipovaca撰写。我知道flip函数接受一个函数并返回一个像原始函数一样的函数,但是前两个参数被翻转。

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

ghci> map (flip subtract 20) [1,2,3,4]
[19,18,17,16]
Run Code Online (Sandbox Code Playgroud)

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

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

Wil*_*sem 8

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

map (flip subtract 20) [1,2,3,4]
Run Code Online (Sandbox Code Playgroud)

等效于:

[flip subtract 20 1, flip subtract 20 2, flip subtract 20 3, flip subtract 20 4]
Run Code Online (Sandbox Code Playgroud)

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]
Run Code Online (Sandbox Code Playgroud)

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

[20 - 1, 20 - 2, 20 - 3, 20 - 4]
Run Code Online (Sandbox Code Playgroud)

因此等同于:

Prelude> map (flip subtract 20) [1,2,3,4]
[19,18,17,16]
Run Code Online (Sandbox Code Playgroud)

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

map (20 -) [1,2,3,4]
Run Code Online (Sandbox Code Playgroud)