What is the difference between the dot (.) and the dollar sign ($)?. As I understand it, they are both syntactic sugar for not needing to use parentheses.

4 upvote
  flag
5 upvote
  flag
To all future learners who find this question: both . and $ are functions in their own right, and you do much better learning what they do as functions than treating them as handy "syntactic sugar" for getting rid of parentheses. – Ben

11 Answers 11

They have different types and different definitions:

infixr 9 .
(.) :: (b -> c) -> (a -> b) -> (a -> c)
(f . g) x = f (g x)

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

($) is intended to replace normal function application but at a different precedence to help avoid parentheses. (.) is for composing two functions together to make a new function.

In some cases they are interchangeable, but this is not true in general. The typical example where they are is:

f $ g $ h $ x

==>

f . g . h $ x

In other words in a chain of $s, all but the final one can be replaced by .

upvote
  flag
What if x was a function? Can you then use . as the final one? – richizy
1 upvote
  flag
@richizy if you're actually applying x in this context, then yes - but then the "final" one would be applying to something other than x. If you're not applying x, then it's no different to x being a value. – Ganesh Sittampalam

Also note that ($) is the identity function specialised to function types. The identity function looks like this:

id :: a -> a
id x = x

While ($) looks like this:

($) :: (a -> b) -> (a -> b)
($) = id

Note that I've intentionally added extra parentheses in the type signature.

Uses of ($) can usually be eliminated by adding parenthesis (unless the operator is used in a section). E.g.: f $ g x becomes f (g x).

Uses of (.) are often slightly harder to replace; they usually need a lambda or the introduction of an explicit function parameter. For example:

f = g . h

becomes

f x = (g . h) x

becomes

f x = g (h x)

Hope this helps!

The short and sweet version:

  • ($) calls the function which is its left-hand argument on the value which is its right-hand argument.
  • (.) composes the function which is its left-hand argument on the function which is its right-hand argument.
up vote 1039 down vote accepted

The $ operator is for avoiding parentheses. Anything appearing after it will take precedence over anything that comes before.

For example, let's say you've got a line that reads:

putStrLn (show (1 + 1))

If you want to get rid of those parentheses, any of the following lines would also do the same thing:

putStrLn (show $ 1 + 1)
putStrLn $ show (1 + 1)
putStrLn $ show $ 1 + 1

The primary purpose of the . operator is not to avoid parentheses, but to chain functions. It lets you tie the output of whatever appears on the right to the input of whatever appears on the left. This usually also results in fewer parentheses, but works differently.

Going back to the same example:

putStrLn (show (1 + 1))
  1. (1 + 1) doesn't have an input, and therefore cannot be used with the . operator.
  2. show can take an Int and return a String.
  3. putStrLn can take a String and return an IO ().

You can chain show to putStrLn like this:

(putStrLn . show) (1 + 1)

If that's too many parentheses for your liking, get rid of them with the $ operator:

putStrLn . show $ 1 + 1
33 upvote
  flag
Actually, since + is a function too, couldn't you make it prefixed then compose it in as well, like ` putStrLn . show . (+) 1 1 ` Not that it's any clearer, but I mean... you could, right? – CodexArcanum
2 upvote
  flag
@CodexArcanum In this example, something like putStrLn . show . (+1) $ 1 would be equivalent. You are correct in that most (all?) infix operators are functions. – Michael Steele
upvote
  flag
After seeing putStrLn $ show $ 1 + 1, I honestly think, $ must be replaced with a light-weight character. I can't think of any right now , because they're all used up, but some character will emerge. – Abdulsattar Mohammed
upvote
  flag
@CodexArcanum: putStrLn . show . (+) 1 1 does not work. – Nawaz
upvote
  flag
@Nawaz Correct, you would have to do something like (putStrLn . show . (+1)) 1 – nightski
71 upvote
  flag
I wonder why nobody ever mentions uses like map ($3). I mean, I mostly use $ to avoid parentheses as well, but it's not like that's all they're there for. – Cubic
3 upvote
  flag
Be very careful with your use of $, though. It tends to continue the parenthesis to the end of the line, or end of the parentheses it is inside. Caused me many strange results when I was learning the language. – simonsays
upvote
  flag
@Cubic what is that map statement supposed to do? – wrongusername
35 upvote
  flag
map ($3) is a function of type Num a => [(a->b)] -> [b]. It takes a list of functions taking a number, applies 3 to all of them and collects the results. – Cubic
1 upvote
  flag
@Cubic, thank you so much, at first I didn't grok what you meant but GHCI's type system helped me! For your edification, my example; ---code-- let try :: [Integer -> b] -> [b] ; try = map ($3) ; let adda :: Integer -> Integer ; adda x = 7 + x; let suba :: Integer -> Integer ; suba x = x - 7; -- now doing it: --; try [adda, suba] ; -- RESULT = [10,-4] ///I apologize we can't format comments as code – AnneTheAgile
11 upvote
  flag
You have to be careful when using $ with other operators. "x + f (y +z)" is not the same as "x + f $ y + z" because the latter actually means "(x+f) (y+z)" (i.e. the sum of x and f is treated as a function). – Paul Johnson
1 upvote
  flag
@AnneTheAgile: If you want a concise example: map ($3) [(\x->x+7),(\x->x-7)]. I tend to read $ as apply to in my head, so you apply the number 3 to two number-transforming functions in a list using map. – Fx32
upvote
  flag
@CodexArcanum No, you could NOT. (+) is a "2 argument function", so your example would not work. You could however do it using composition of function composition (so called "tits operator"): putStrLn ((.).(.)) show ((.).(.)) (+) $ 1 1. I usually define (.:) = (.).(.) and then (putStrLn . show) .: (+) $ 1 1 works fine :) – Wojciech Danilo

($) allows functions to be chained together without adding parentheses to control evaluation order:

Prelude> head (tail "asdf")
's'

Prelude> head $ tail "asdf"
's'

The compose operator (.) creates a new function without specifying the arguments:

Prelude> let second x = head $ tail x
Prelude> second "asdf"
's'

Prelude> let second = head . tail
Prelude> second "asdf"
's'

The example above is arguably illustrative, but doesn't really show the convenience of using composition. Here's another analogy:

Prelude> let third x = head $ tail $ tail x
Prelude> map third ["asdf", "qwer", "1234"]
"de3"

If we only use third once, we can avoid naming it by using a lambda:

Prelude> map (\x -> head $ tail $ tail x) ["asdf", "qwer", "1234"]
"de3"

Finally, composition lets us avoid the lambda:

Prelude> map (head . tail . tail) ["asdf", "qwer", "1234"]
"de3"
1 upvote
  flag
If the stackoverflow had a combination function, I would prefer the answer combining the previous two explanations with the example in this answer. – Chris.Q

One application that is useful and took me some time to figure out from the very short description at learn you a haskell: Since:

f $ x = f x

and parenthesizing the right hand side of an expression containing an infix operator converts it to a prefix function, one can write ($ 3) (4+) analogous to (++", world") "hello".

Why would anyone do this? For lists of functions, for example. Both:

map (++", world") ["hello","goodbye"]`

and:

map ($ 3) [(4+),(3*)]

are shorter than map (\x -> x ++ ", world") ... or map (\f -> f 3) .... Obviously, the latter variants would be more readable for most people.

11 upvote
  flag
btw, I'd advise against using $3 without the space. If Template Haskell is enabled, this will be parsed as a splice, whereas $ 3 always means what you said. In general there seems to be a trend in Haskell to "stealing" bits of syntax by insisting that certain operators have spaces around them to be treated as such. – Ganesh Sittampalam
upvote
  flag
Took me a while to figure out how the parentheses were working: en.wikibooks.org/wiki/Haskell/… – Casebash

... or you could avoid the . and $ constructions by using pipelining:

third xs = xs |> tail |> tail |> head

That's after you've added in the helper function:

(|>) x y = y x
1 upvote
  flag
Yes, |> is the F# pipeline operator. – user1721780
5 upvote
  flag
One thing to note here, is that Haskell's $ operator actually works more like F#'s <| than it does |>, typically in haskell you'd write the above function like this: third xs = head $ tail $ tail $ xs or perhaps even like third = head . tail . tail, which in F#-style syntax would be something like this: let third = List.head << List.tail << List.tail – Electric Coffee
upvote
  flag
Why add a helper function to make Haskell look like F#? -1 – vikingsteve
6 upvote
  flag
The flipped $ is already available, and it's called & hackage.haskell.org/package/base-4.8.0.0/docs/… – pat

My rule is simple (I'm beginner too):

  • do not use . if you want to pass the parameter (call the function), and
  • do not use $ if there is no parameter yet (compose a function)

That is

show $ head [1, 2]

but never:

show . head [1, 2]
1 upvote
  flag
Good heuristic, but could use more examples – Zoey Hewll

A great way to learn more about anything (any function) is to remember that everything is a function! That general mantra helps, but in specific cases like operators, it helps to remember this little trick:

:t (.)
(.) :: (b -> c) -> (a -> b) -> a -> c

and

:t ($)
($) :: (a -> b) -> a -> b

Just remember to use :t liberally, and wrap your operators in ()!

I think a short example of where you would use . and not $ would help clarify things.

double x = x * 2
triple x = x * 3
times6 = double . triple

:i times6
times6 :: Num c => c -> c

Note that times6 is a function that is created from function composition.

Haskell: difference between . (dot) and $ (dollar sign)

What is the difference between the dot (.) and the dollar sign ($)?. As I understand it, they are both syntactic sugar for not needing to use parentheses.

They are not syntactic sugar for not needing to use parentheses - they are functions, - infixed, thus we may call them operators.

(.) is the compose function. So

result = (f . g) x

is the same as building a function that passes the result of its argument passed to g on to f.

h = \x -> f (g x)
result = h x

($) is a right-associative apply function with low binding precedence. So it merely calculates the things to the right of it first. Thus,

result = f $ g x

is the same as this, procedurally (which matters since Haskell is evaluated lazily, it will begin to evaluate f first):

h = f
g_x = g x
result = h g_x

or more concisely:

result = f (g x)

We can see this by reading the source for each function.

Read the Source

Here's the source for (.):

-- | Function composition.
{-# INLINE (.) #-}
-- Make sure it has TWO args only on the left, so that it inlines
-- when applied to two functions, even if there is no final argument
(.)    :: (b -> c) -> (a -> b) -> a -> c
(.) f g = \x -> f (g x)

And here's the source for ($):

-- | Application operator.  This operator is redundant, since ordinary
-- application @(f x)@ means the same as @(f '$' x)@. However, '$' has
-- low, right-associative binding precedence, so it sometimes allows
-- parentheses to be omitted; for example:
--
-- >     f $ g $ h x  =  f (g (h x))
--
-- It is also useful in higher-order situations, such as @'map' ('$' 0) xs@,
-- or @'Data.List.zipWith' ('$') fs xs@.
{-# INLINE ($) #-}
($)                     :: (a -> b) -> a -> b
f $ x                   =  f x

When to use:

Use composition when you do not need to immediately evaluate the function. Maybe you want to pass the function that results from composition to another function.

Use application when you are supplying all arguments for full evaluation.

So for our example, it would be semantically preferable to do

f $ g x

when we have x (or rather, g's arguments), and do:

f . g

when we don't.

Not the answer you're looking for? Browse other questions tagged or ask your own question.