Haskell dollar operator application

2.2k views Asked by At

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?

4

There are 4 answers

4
AudioBubble On BEST ANSWER

($) 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
0
misterbee On

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.

0
ДМИТРИЙ МАЛИКОВ On

($ 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

1
Satvik On

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