简体   繁体   English

Haskell中的$ mean / do是什么?

[英]What does $ mean/do in Haskell?

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

$ is infix "application". $是中缀“应用程序”。 It's defined as 它被定义为

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

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

It's useful for avoiding extra parentheses: f (gx) == f $ gx . 它有助于避免额外的括号: f (gx) == f $ gx

A particularly useful location for it is for a "trailing lambda body" like 对于它来说,一个特别有用的位置是“尾随λ体”

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

compared to 相比

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

Or, trickily, it shows up sectioned sometimes when expressing "apply this argument to whatever function" 或者,巧妙的是,它有时会在表达“将此参数应用于任何函数”时显示为剖面图

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

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

I like to think of the $ sign as a replacement for parenthesis. 我想把$符号作为括号的替代。

For example, the following expression: 例如,以下表达式:

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

What happens if we don't put the $? 如果我们不把$? Then we would get 然后我们会得到

take 1 filter even [1..10]

and the compiler would now complain, because it would think we're trying to apply 4 arguments to the take function, with the arguments being 1 :: Int , filter :: (a -> Bool) -> [a] -> [a] , even :: Integral a => a -> Bool , [1..10] :: [Int] . 编译器现在会抱怨,因为它会认为我们试图将4个参数应用于take函数,参数为1 :: Intfilter :: (a -> Bool) -> [a] -> [a]even :: Integral a => a -> Bool[1..10] :: [Int]

This is obviously incorrect. 这显然是不正确的。 So what can we do instead? 那么我们可以做些什么呢? Well, we could put parenthesis around our expression: 好吧,我们可以在括号中加上括号:

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

This would now reduce to: 现在这将减少到:

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

which then becomes: 然后变成:

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

But we don't always want to be writing parenthesis, especially when functions start getting nested in each other. 但是我们并不总是想要写括号,特别是当函数开始相互嵌套时。 An alternative is to place the $ sign between where the pair of parenthesis would go, which in this case would be: 另一种方法是将$符号放在括号对的位置之间,在这种情况下将是:

take 1 $ filter even [1..10]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM