7

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

Ok I understand that this:

f(g(x))

can be rewritten:

f $ g(x)

and can also be rewritten:

f . g(x)

What I don't fully grasp is where the two DO NOT overlap in functionality. I conceptually understand that they don't fully overlap, but could someone clarify this for me once and for all?

Community
  • 1
  • 1
Ramy
  • 19,312
  • 38
  • 98
  • 146
  • 1
    Look, you actually can'twrite like in your second example. Tryi ghci! – fuz Feb 02 '11 at 16:13
  • 6
    Also, parens are not needed (and not recommended) for function calls. In summary, the examples should be `f (g x)`, `f $ g x` and `(f . g) x`. –  Feb 02 '11 at 16:16

3 Answers3

21
Prelude> :t ($)
($) :: (a -> b) -> a -> b
Prelude> :t (.)
(.) :: (b -> c) -> (a -> b) -> a -> c

$ applies a function to a value. . composes two functions.

So I can write f $ g x which is "apply f to (g of x)" or f . g $ x which is "apply the composition of f and g to x". One common style is to pile up dots on the left with a dollar trailing. The reason is that f $ g $ x means the same thing as f . g $ x but the expression f $ g on its own is often meaningless (in fact, possibly a type error) while the expression f . g means "the composition of f and g"

sclv
  • 38,237
  • 6
  • 94
  • 202
  • 3
    `f $ g` is perfectly possible and well-typed for countless `f` and `g` (consider `(\f -> f 0) $ (\x -> x + 1)`), it's just identical to `f g`. Otherwise, correct. –  Feb 02 '11 at 16:20
  • @delnan I can't think of a `f $ g` that is well-typed on its own *and* in the context of `f $ g $ x`. But that could be a failure of imagination. – sclv Feb 02 '11 at 16:40
  • 1
    If `f` takes and returns a function, it's possible. Example: `const (f :: a -> b) $ (g :: c -> d) :: a -> b` and `const (f :: a -> b) $ (g :: c -> d) $ (... :: a) :: b`. Of course it's much harder to find a meaningful/real-world example, but w.r.t. the type system there's nothing exceptional about it. –  Feb 02 '11 at 16:53
  • edited to take into account your point. thanks. – sclv Feb 03 '11 at 01:58
14

Additionaly to what was already said, you need the $ as "function application glue" in cases like this:

map ($3) [(4+),(5-),(6*),(+4),(*5),(^6)]
--[7,2,18,7,15,729] 

Neither (.3) nor (3) will work in the example.

Landei
  • 53,406
  • 12
  • 92
  • 191
1

"f $ g x" cannot be rewritten to "f . g x". In fact, the compiler won't even accept the second function, because "(.)" has the type "(b -> c) -> (a -> b) -> (a -> c)". I.e the second argument must be a function, but "g x" is a value not a function.

keiter
  • 3,494
  • 26
  • 38