$ 在 Haskell 中是啥意思/做啥?

Posted

技术标签:

【中文标题】$ 在 Haskell 中是啥意思/做啥?【英文标题】:What does $ mean/do in Haskell?$ 在 Haskell 中是什么意思/做什么? 【发布时间】:2013-10-31 12:32:42 【问题描述】:

当您编写稍微复杂一点的函数时,我注意到$ 被大量使用,但我不知道它的作用是什么?

【问题讨论】:

这是“应用”运算符。这个博客在介绍它的基础方面做得很好:snakelemma.blogspot.com/2009/12/dollar-operator-in-haskell.html Reverse duplicate. 【参考方案1】:

$ 是中缀“应用程序”。它被定义为

($) :: (a -> b) -> (a -> b)
f $ x = f x

-- or 
($) f x = f x
-- or
($) = id

这对于避免额外的括号很有用:f (g x) == f $ g x

一个特别有用的位置是“尾随 lambda 体”,如

forM_ [1..10] $ \i -> do
  l <- readLine
  replicateM_ i $ print l

相比

forM_ [1..10] (\i -> do
  l <- readLine
  replicateM_ i (print l)
)

或者,巧妙的是,它有时会在表达“将此参数应用于任何函数”时显示为分段

applyArg :: a -> (a -> b) -> b
applyArg x = ($ x)

>>> map ($ 10) [(+1), (+2), (+3)]
[11, 12, 13]

【讨论】:

是的。有时也写成f . g . h $ x,也可能是(f . g . h) x 技术说明:AFAIK,目前$的定义有点假。 GHC 实际上将其视为语法,以便 runST $ do 成语起作用(除了在它真正是函数的部分之外)。它应该只是一个函数,但更高级别的类型是一个问题。 同意—source from Simon Peyton Jones here &lt;$&gt; 只是中缀fmap。据我所知,它并没有什么特别之处。 可能值得指出,连同运算符的签名,它的 PRECEDENCE 为 0。因此,一切都比 $ 绑定得更紧密。【参考方案2】:

我喜欢将 $ 符号视为括号的替代品。

例如下面的表达式:

take 1 $ filter even [1..10] 
-- = [2]

如果我们不放 $ 会发生什么?然后我们会得到

take 1 filter even [1..10]

编译器现在会抱怨,因为它会认为我们正在尝试将 4 个参数应用于 take 函数,参数为 1 :: Intfilter :: (a -&gt; Bool) -&gt; [a] -&gt; [a]even :: Integral a =&gt; a -&gt; Bool[1..10] :: [Int]

这显然是不正确的。那么我们能做些什么呢?好吧,我们可以在表达式周围加上括号:

(take 1) (filter even [1..10])

现在这将简化为:

(take 1) ([2,4,6,8,10])

然后变成:

take 1 [2,4,6,8,10]

但我们并不总是想写括号,尤其是当函数开始相互嵌套时。另一种方法是将$ 符号放在括号对的位置之间,在本例中为:

take 1 $ filter even [1..10]

【讨论】:

编译器如何推断括号末尾的位置? 当它找到下一个$ 符号时,否则为行尾。

以上是关于$ 在 Haskell 中是啥意思/做啥?的主要内容,如果未能解决你的问题,请参考以下文章

`undefined` 的类型签名在 Haskell 中是啥意思?

$做啥? $0 $1 $2 在 shell 脚本中是啥意思? [复制]

“|”是啥意思(单管道)在 JavaScript 中做啥?

“?”是啥意思?和“:”在布尔语句中做啥? [复制]

“启用加载”和“包括在报告刷新中”是啥意思/做啥?

??!??! 是啥意思?运算符在 C 中做啥?