The purpose of a $
is to help reduce the number of parentheses ()
in your expressions. Here's its type signature:
($) :: (a -> b) -> a -> b
In other words, all it does is take a function and its single argument, and applies the function. Really boring. Terrifically boring. That is to say:
($) f x = f x , or more simply,
($) f = f , or more simply,
($) = id
The only thing which makes ($)
worthwhile is that it has a different precedence than a regular function like id
. That is, ($)
has a very low precedence; in contrast, regular functions such as id
have a very high precedence in application.
When acting as an infix operator, $
is right associative. That's another useful property.
Question 1: Why ($) not works on "p $ 2 $ 2 $ 5"?
Let's get rid of some $
signs. The following are all equivalent:
p $ 2 $ 2 $ 5
= p (2 $ 2 $ 5)
= p (2 (2 $ 5))
= p (2 (2 5))
I suppose you can figure out why an expression like (2 5)
doesn't make any sense.
Question 2: Why ($$) works on "p $$ 2 $$ 2 $$ 5"?
When you define a new function such as ($$)
, it is given left assosciativity (and also highest precedence) by default. Then:
p $$ 2 $$ 2 $$ 5
= (p 2) $$ 2 $$ 5
= ((p 2) 2) $$ 5
= ((p 2) 2) 5
This is of course plain old partial application.
Question 3: Why ($$) not works on "p $$ [1]++[2..3] $$ 4 $$ 5"?
p $$ [1] ++ [2..3] $$ 4 $$ 5
= (((p $$ [1]) ++ [2..3]) $$ 4) $$ 5
= (((p [1]) ++ [2..3]) 4) 5
Question 4: Is there a more elegant way to write "p $$ [1]++[2..3] $$ [1]++[2..3] $$ 5" correctly?
Without the wacky $$
, I suppose. :)