当你在写稍微复杂一点的函数时,我注意到$被用了很多次,但我不知道它是做什么的?
$
2jcobegt1#
$是中缀“application”,定义为
($) :: (a -> b) -> a -> b f $ x = f x -- or ($) f x = f x -- or ($) = id
这对于避免额外的括号很有用:f (g x) == f $ g x。它的一个特别有用的位置是“尾随lambda主体”,如
f (g x) == f $ g x
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]
ryevplcw2#
我喜欢把$符号看作是括号的替代。例如,以下表达式:
take 1 $ filter even [1..10] -- = [2]
如果我们不放美元会怎么样?
take 1 filter even [1..10]
编译器现在会抱怨,因为它会认为我们试图向take函数应用4个参数,参数是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]
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]
2条答案
按热度按时间2jcobegt1#
$
是中缀“application”,定义为这对于避免额外的括号很有用:
f (g x) == f $ g x
。它的一个特别有用的位置是“尾随lambda主体”,如
相比
或者,巧妙的是,在表达“将此参数应用于任何函数”时,它有时会显示为分段
ryevplcw2#
我喜欢把$符号看作是括号的替代。
例如,以下表达式:
如果我们不放美元会怎么样?
编译器现在会抱怨,因为它会认为我们试图向
take
函数应用4个参数,参数是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]