67

When you are writing slightly more complex functions I notice that $ is used a lot but I don't have a clue what it does?

Benjamin Hodgson
  • 42,952
  • 15
  • 108
  • 157
Eddie
  • 897
  • 2
  • 7
  • 12
  • It's the "apply" operator. This blog does an alright job getting the basic of it covered: http://snakelemma.blogspot.com/2009/12/dollar-operator-in-haskell.html – vcsjones Oct 22 '13 at 14:56

2 Answers2

79

$ 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 (g x) == f $ g x.

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]
cafce25
  • 15,907
  • 4
  • 25
  • 31
J. Abrahamson
  • 72,246
  • 9
  • 135
  • 180
  • 5
    Yep. It's also written `f . g . h $ x` sometimes, which could also be `(f . g . h) x`. – J. Abrahamson Oct 22 '13 at 15:07
  • 5
    Technical note: AFAIK, the definition of `$` is a bit of a lie at present. GHC actually treats it as syntax so that the `runST $ do` idiom works (except in things like sections where it really is a function). It should be just a function, but higher rank types are a problem. – Philip JF Oct 23 '13 at 00:23
  • 1
    Agreed—[source from Simon Peyton Jones here](http://www.mail-archive.com/glasgow-haskell-users@haskell.org/msg18923.html) – J. Abrahamson Oct 23 '13 at 00:37
  • `<$>` is just infix `fmap`. It doesn't do anything special as far as I know. – J. Abrahamson Dec 06 '14 at 19:13
  • 3
    It might be worth pointing out, along with the operators's signature, that its PRECEDENCE is 0. So, everything binds more tightly than $. – JohnL4 Aug 20 '15 at 13:50
  • What if I write (10 $) in your last example. It doesn't produce any output. – MD05 Nov 11 '16 at 23:34
  • @johnbakers `(a->b)->a->b` is same as `(a->b)->(a->b)` because `->` is right associative. – kishlaya May 11 '18 at 05:08
30

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].

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]

Jan D.M.
  • 2,284
  • 2
  • 20
  • 32
stephen
  • 1,617
  • 3
  • 20
  • 27