$是可以代替括号的一种符号
例如,下面的代码
Prelude> take 1 $ filter even [1..10]
[2]
如果我们去掉$会怎么样呢?
Prelude> take 1 filter even [1..10]
<interactive>:3:1: error:
• Couldn't match expected type ‘(Integer -> Bool)
-> [Integer] -> t’
with actual type ‘[a1]’
• The function ‘take’ is applied to four arguments,
but its type ‘Int -> [a1] -> [a1]’ has only two
In the expression: take 1 filter even [1 .. 10]
In an equation for ‘it’: it = take 1 filter even [1 .. 10]
• Relevant bindings include it :: t (bound at <interactive>:3:1)
<interactive>:3:9: error:
• Couldn't match expected type ‘[a1]’
with actual type ‘(a0 -> Bool) -> [a0] -> [a0]’
• Probable cause: ‘filter’ is applied to too few arguments
In the second argument of ‘take’, namely ‘filter’
In the expression: take 1 filter even [1 .. 10]
In an equation for ‘it’: it = take 1 filter even [1 .. 10]
我们可以看到如果去掉$,编译器则会报错,因为编译器以为我们拿四个参数给take函数,(四个参数为:1 :: Int
, filter :: (a -> Bool) -> [a] -> [a]
, even :: Integral a => a -> Bool
, [1..10] :: [Int]
),然而实际take只能使用一个参数。
- 那我们应该怎么做呢?
在表达式周围加上括号:
(take 1) (filter even [1..10])
然后继续简化:
(take 1) ([2,4,6,8,10])
但是我们并不总是想写括号,尤其是当函数开始相互嵌套时。另一种选择是在圆括号对之间插入$符号,在这种情况下为:
take 1 $ filter even [1..10]