如何理解Haskell中的这个`$`用法

del*_*lta 2 syntax haskell operators dollar-sign operator-sections

这种情况发生在你想将一堆函数应用于同一个变量的情况下,它可能如下所示:

map (\f->f 4) [odd, even]
Run Code Online (Sandbox Code Playgroud)

但是从LYAH使用$它非常整洁

map ($ 4) [odd, even]
Run Code Online (Sandbox Code Playgroud)

为什么会这样呢?首先我在ghci中键入它$ 4 odd,它失败了,然后我打字($ 4) odd,它工作正常.然后我检查($ 4)使用:t哪个显示的类型($ 4) :: Num a => (a -> b) -> b,oddodd :: Integral a => a -> Bool.这似乎有道理,但对我来说仍然不清楚.

任何人都可以清楚地解释它,它是另一种常见用法$,还有其他更多的用法$.

Sho*_*hoe 7

操作员的剖析

$应用程序操作的格式为:

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

当你想要避免一对尾随的括号时,经常会出现这种情况:

func a (b + c)
Run Code Online (Sandbox Code Playgroud)

等于:

func a $ b + c
Run Code Online (Sandbox Code Playgroud)

这背后的魔力只是在其固定性声明中解释:

infixr 0
Run Code Online (Sandbox Code Playgroud)

这意味着:后面的所有内容$将被分组到一个实体中,就像它们括在括号中一样.

当然这也可以像这样"嵌套":

func a $ b + other $ c - d
Run Code Online (Sandbox Code Playgroud)

意思是:

func a (b + other (c - d))
Run Code Online (Sandbox Code Playgroud)

应用运算符作为函数

您的案例非常有趣,根据我的经验,不经常使用.

我们来分析一下:

map ($ 4) [odd, even]
Run Code Online (Sandbox Code Playgroud)

我们知道map的类型是:

map :: (a -> b) -> [a] -> [b]
Run Code Online (Sandbox Code Playgroud)

行为,如果有人忘了,方法是:取第一个参数(从功能ab),它适用于所有a的第二个参数列表中,最后返回结果列表.

你可以看到($ 4)"将4作为参数传递给某些东西".意思就是:

($ 4) func
Run Code Online (Sandbox Code Playgroud)

是相同的:

func $ 4
Run Code Online (Sandbox Code Playgroud)

所以:

map ($ 4) [odd, even]
Run Code Online (Sandbox Code Playgroud)

手段:

[($ 4) odd, ($ 4) even]
[(odd $ 4), (even $ 4)]
[False, True]
Run Code Online (Sandbox Code Playgroud)

为什么(func $)没有必要

你可能会说,就像你可以做(/ 4),并(2 /)分别表示"除以4的东西"和"东西分2",你可以做($ 4)(func $),你会是正确的.

事实上:

(func $) 4
Run Code Online (Sandbox Code Playgroud)

是相同的:

func $ 4
func 4
Run Code Online (Sandbox Code Playgroud)

这与:

($ 4) func
Run Code Online (Sandbox Code Playgroud)

但现实是:

map (func $) [...]
Run Code Online (Sandbox Code Playgroud)

将是不必要的,因为第一个参数map始终应用于列表的每个参数,使得上面的相同:

map func [...]
Run Code Online (Sandbox Code Playgroud)