views:

2978

answers:

6

Can anybody explain what the difference is in Haskell between the dot (.), and the dollar sign ($). As I understand it, they are both syntactic sugar for not needing to use parentheses.

+32  A: 

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 .

Ganesh Sittampalam
+19  A: 

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!

Martijn
+3  A: 

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.

ellisbben
+23  A: 

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

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

putStrLn (show (1 + 1))

If you want to get rid of those parenthesis, 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 parenthesis, 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 parenthesis, but 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 parenthesis for your liking, get rid of them with the '$' operator:

putStrLn . show $ 1 + 1
Michael Steele
This is the clearest explanation on this page. Thanks.
mindeavor.
This makes the most sense by far. Great work.
CharlesS
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
+3  A: 

($) 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"
softmechanics
+2  A: 

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.

Christoph
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
Took me a while to figure out how the parentheses were working: http://en.wikibooks.org/wiki/Haskell/More_on_functions#Infix_versus_Prefix
Casebash