Haskell参数通过'map'中的'$ x'应用于inflix运算符函数列表.它是如何工作的?

Arm*_*pen 1 optimization haskell functional-programming list map-function

我想知道,出于好奇心,这个函数是如何通过某种优化产生的中间表达式?我确实理解$实际上是一个函数,它只提供一个参数.不知何故,通过将这个函数应用到'map'提供的列表中的函数,它设法看到'$'函数缺少一个函数,正如我所提到的那样是由'map'提供的.这种优化行为对于'$'的函数应用程序来说是独一无二的吗?因为,为了它的价值我无法看到它将如何从'map'和'$'的函数定义中得到,我在下面提供了方便.

从一开始,似乎'$ 3'应该出现在函数表达式之前,但是这样的表达式不会在编译器中进行评估.这是优化的扩展中间表达式,似乎正在发生:

[(4+) $3, (10*) $3, (^2) $3, sqrt $3]
Run Code Online (Sandbox Code Playgroud)

定义 - $

($) :: (a -> b) -> a -> b  
f $ x = f x
Run Code Online (Sandbox Code Playgroud)

定义 - 地图

map :: (a -> b) -> [a] -> [b]  
map _ [] = []  
map f (x:xs) = f x : map f xs  
Run Code Online (Sandbox Code Playgroud)

使用的例子

map ($ 3) [(4+), (10*), (^2), sqrt]
Run Code Online (Sandbox Code Playgroud)

返回结果

[7.0,30.0,9.0,1.7320508075688772]
Run Code Online (Sandbox Code Playgroud)

Wil*_*sem 7

如果我理解你的问题,你会想知道如果你写的($ 3)会怎么样?

Haskell语法有一个名为" 中缀运算符的部分 " 的概念.这意味着如果你用一个运算符(这里+)写一个表达式,那么:

(2 +) == \x -> 2 + x == (+) 2
(+ 2) == \x -> x + 2 == flip (+) 2
Run Code Online (Sandbox Code Playgroud)

Haskell是一种函数式编程语言.函数式编程语言的一个方面是可以将函数作为参数.这不仅限于函数式编程语言:在Java,C#,C++等中,您可以将函数/方法引用传递给函数/方法,例如使用参数调用这些函数.

所以你写了:

map (\x -> ($) x 3) [(4+), (10*), (^2), sqrt]
Run Code Online (Sandbox Code Playgroud)

而且\x -> ($) x 3只是一个普通的功能.因此,如果我们将其应用于第一个参数,我们得到:

(\x -> ($) x 3) (4+)
-> ($) (4+) 3
-> (4+) 3
-> 4 + 3
-> 7
Run Code Online (Sandbox Code Playgroud)

因此,没有什么特别的($ 3)情况,它适用于我们只填写操作员右侧的任何操作员.

事实上,你已经使用过这个概念了(^2).您的列表实际上看起来像:

map (flip ($) 3) [(+) 4, (*) 10, flip (^) 2, sqrt]
Run Code Online (Sandbox Code Playgroud)

因此,您在列表的元素中使用了左侧和右侧的切片.