$ 在 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
<$>
只是中缀fmap
。据我所知,它并没有什么特别之处。
可能值得指出,连同运算符的签名,它的 PRECEDENCE 为 0。因此,一切都比 $ 绑定得更紧密。【参考方案2】:
我喜欢将 $ 符号视为括号的替代品。
例如下面的表达式:
take 1 $ filter even [1..10]
-- = [2]
如果我们不放 $ 会发生什么?然后我们会得到
take 1 filter even [1..10]
编译器现在会抱怨,因为它会认为我们正在尝试将 4 个参数应用于 take
函数,参数为 1 :: Int
、filter :: (a -> Bool) -> [a] -> [a]
、even :: Integral a => a -> 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 中是啥意思?