12

I'm having trouble with understanding how function application works with currying in haskell. If I have following function:

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

I understand that to partially apply this function I need to provide (a -> b) function ($'s first argument).

Why then is it possible to apply a value first (i.e. reverse arguments)?

($ 0) :: Num a => (a -> b) -> b

What am I missing here?

Benjamin Hodgson
  • 42,952
  • 15
  • 108
  • 157
Rumca
  • 1,809
  • 12
  • 17

4 Answers4

14

($) is an operator. In Haskell, any operator can be written in a left-section (like (x $)) or a right-section (like ($ x)):

(x $) = (\y -> x $ y) = ($) x
($ x) = (\y -> y $ x) = flip ($) x

Note that the only exception to this rule is (-), in order to conveniently write negative numbers:

\x -> (x-) :: Num a => a -> a -> a  -- equivalent to \x -> (-) x
\x -> (-x) :: Num a => a -> a       -- equivalent to \x -> negate x

In case you want to tersely write (\y -> y - x), you can use subtract:

\x -> subtract x :: Num a => a -> a -> a  -- equivalent to \x -> flip (-) x
  • Thanks, this explains why it is working this way. Are those definitions language features or can they be found somewhere in sources? – Rumca Jan 18 '13 at 21:32
  • 2
    @Rumca Not really in the source, (x $) and ($ x) are sections and a description of them can be found in the [2010 haskell report](http://www.haskell.org/onlinereport/haskell2010/) in the [sections section](http://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-300003.5). – Davorak Jan 18 '13 at 21:45
  • The language is described in the [Haskell 2010 Report](http://www.haskell.org/onlinereport/haskell2010/). – Luis Casillas Jan 18 '13 at 21:46
  • 1
    The "Section" syntax `(x $) = ...` isn't a definition in the sense of "function definition" it is part of the language syntax, and it applies to every function, not just `$`. (Only makes sense for functions that can take >=2 arguments, of course.) – misterbee Dec 28 '13 at 01:13
4

($ 0)(\x -> x $ 0)(\x -> ($) x 0)

If ($) :: (a -> b) -> a -> b) and we applied second argument like (\x -> ($) x 0) we have :: Num a => (a -> b) -> b

2

You are confusing the infix notation of an operator with a function.

> :t (($) (+1))
(($) (+1)) :: Num b => b -> b

Here are some forms of expressions with $, for better understanding:

a $ b => ($) a b

($ b) => flip ($) b => (\b a -> ($) a b) b => \a -> ($) a b

(a $) => ($) a => \b -> ($) a b

Community
  • 1
  • 1
Satvik
  • 11,238
  • 1
  • 38
  • 46
  • -1 Even as someone who firmly understands what this question is about and what the reasoning is, I find this answer incomprehensible. How is someone who doesn't know Haskell very well supposed to make sense of this? No explanation of what the difference is between operators and functions at all. `$ b => flip ($) b => \a -> ($) a b` is not even valid syntax. (Edit: Alright will it would be -1 if I had a little more rep.) – John Tyree Jan 20 '13 at 12:19
1

Note also that in Haskell syntax, alphanumeric names are distinguished from punctuation names.

An alphanumeric function foo1 a b is prefix by default, and becomes infix if you add backticks: a `foo` b.

A punctuation-named function like $ or <*> is infix by default, and becomes prefix if you add parentheses ($) or (<*>). This is just syntax sugar for the programmer familiar with the Latin alphabet; it is an arbitrary but helpful distinction between alphanumeric names and punctuation names.

Both kinds of functions are just functions, they don't have the special semantic rules that we have for "operators" in C++ or Java. It's just the syntax rules around prefix/infix and backticks/parentheses that are different between punctuation-named functions and alphanumeric-named functions.

Will Ness
  • 70,110
  • 9
  • 98
  • 181
misterbee
  • 5,142
  • 3
  • 25
  • 34