0

What are the functions that begin with ($) or (>>=) supposed to do. I'm not asking exactly what $ or >>= mean but I understand that

f :: Int -> Int
f x = x+2

is a function that takes an integer and adds two, but whilst learning Haskell I've ran into problems where the solution has been something like the following:

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

from What does $ mean/do in Haskell?

I assume this means the function ($) takes a lambda (a -> b) and outputs a lambda (a -> b), and then the next line I'm unsure.

but I always assumed the function definition

f :: Int -> Int

had to be followed by a function with arguments starting with f like my first code example.

Thanks

msanford
  • 11,803
  • 11
  • 66
  • 93
f23aaz
  • 339
  • 2
  • 13

1 Answers1

7

Infix applications like 1 + 2 or f $ x are just syntactic sugar for (+) 1 2 and ($) f x, respectively. This is regardless of whether they appear in a pattern match (left side of =) or in an expression. So, your snippets desugar to

f :: Int -> Int
f x = (+) x 2

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

The latter could also be written

apply :: (a -> b) -> a -> b
apply f x = f x

The syntax rule is: if an identifier consists of letters (and possibly numbers, in non-leading position) it's parsed as a function with all arguments on the right, or simply as a constant value if there are no arguments. If it consists of any other symbols and is not surrounded by parentheses, it's parsed as an infix, i.e. desugared so whatever stands on the left is used as the first argument and whatever stands on the right the second argument.

leftaroundabout
  • 117,950
  • 5
  • 174
  • 319
  • So I understand the infix and prefix notation and I've written the functions with those three functions and I can test them in ghci to output what I expect with f 2 and apply (\x -> x+1) 5 But how do I test the ($) function to see how it works? – f23aaz Dec 28 '17 at 01:05
  • Like `(\x -> x + 1) $ 5` or `log $ exp 37`. The `$` doesn't really do much at all, it's main purpose is to group expressions: because it's an infix with very low fixity, it acts usually as if both sides were in parentheses, even if they aren't. – leftaroundabout Dec 28 '17 at 01:07
  • @w1220 one way to use `($)` to do a little more than nothing is to pass it around partially applied. For instance if `evaluateAt1 = ($ 1)`, then `evaluateAt1 succ` gives `2`, or `map ($ x) [f, g, h]` gives `[f x, g x, h x]`. – aplainzetakind Dec 28 '17 at 01:28
  • @leftaroundabout Using those examples without adding the ($) function in my code I can understand the purpose of $ but I when I add the ($) function in your answer into my code I run into problems. Why do people write ($) :: ... f $ x ... as the function definition doesn't match the second line? – f23aaz Dec 28 '17 at 01:29
  • @w1220 it does match the second line, albeit only after desugaring. – leftaroundabout Dec 28 '17 at 01:38