Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between $ and ()

I started learning Haskell and I encountered a problem I can't just understand. I've got a method used to find value from a list of key-value list (from this page):

let findKey key xs = snd . head . filter (\(k,v) -> key == k) $ xs  

I tried fiddling with a bit and decided to get rid of $ sign in this way:

let findKey key xs = snd . head . filter (\(k,v) -> key == k) ( xs )

However, it doesn't even parse (filter applied to too many argumens error). I've read that $ sign is used to simply replace parenthesis and I can't figure out why this simple change of code is bad. Could someone explain it to me?

like image 455
TheMP Avatar asked Jun 17 '14 18:06

TheMP


People also ask

What is the difference between >>> and >>>?

The unsigned right shift operator ">>>" shifts a zero into the leftmost position, while the leftmost position after ">>" depends on sign extension. Show activity on this post. >>> will always put a 0 in the left most bit, while >> will put a 1 or a 0 depending on what the sign of it is. Show activity on this post.

What is the difference between% and/in JavaScript?

‘%’ is modulo operator while ‘ /’ is a division operator. If we’ll talk as compiler-developers, the “%” operator may be a modulo, or the first operator of digraphs, and the “/” operator may be the first part on one-line-comment, or may be a division operator, or may be the part of “/=” operator.

What is the difference between/and% in Java?

Both / and % are two different operators used in Java. These operators are mathematical operators and both have different uses. / Only perform the division operation in mathematics and returns results as the quotient, while % is known as modulus and returns results as the remaining part performed.

What is the difference between% and/in C programming?

Both ‘%’ and ‘/’ are binary operators. ‘%’ is known as the modulus operator or the remainder operator; it is used to find the remainder of division of two numbers. ‘/’ is known as the division operator; it is used to find the quotient in the division of two numbers.


2 Answers

The infix operator ($) is just "function application". In other words

 f   x     -- and
 f $ x

are the same. Since in Haskell parentheses are only used to disambiguate precedence (and for tuple notation and a few other minor places, see comments) we can also write the above in a few other ways

 f     x
 f  $  x
(f)    x
 f    (x)
(f)   (x)    -- and even
(f) $ (x)

In every case, the above expressions denote the same thing: "apply the function f to the argument x".

So why have all this syntax? ($) is useful for two reasons

  1. It has really low precedence so it can stand in for a lot of parentheses sometimes
  2. It's nice to have an explicit name for the action of function application

In the first case, consider the following deeply right-nested function application

f (g (h (i (j x))))

It can be a little difficult to read this and a little difficult to know you have the right number of parentheses. However, it's "just" a bunch of applications so there ought to be a representation of this phrase using ($). Indeed there is

 f $ g $ h $ i $ j $ x

Some people find this easier to read. More modern style also incorporates (.) in order to emphasize that the whole left side of this phrase is just a composed pipeline of functions

 f . g . h . i . j $ x

And this phrase is, as we saw above, identical to

(f . g . h . i . j)  x

which is sometimes nicer to read.


There are also times when we want to be able to pass around the idea of function application. For instance, if we have a list of functions

lof :: [Int -> Int]
lof = [ (+1), (subtract 1), (*2) ]

we might want to map application by a value over them, for instance apply the number 4 to each function

> map (\fun -> fun 4) lof
[ 5, 3, 8 ]

But since this is just function application, we can also use section syntax over ($) to be a bit more explicit

> map ($ 4) lof
[ 5, 3, 8 ]
like image 74
J. Abrahamson Avatar answered Oct 16 '22 15:10

J. Abrahamson


The operator $ has the lowest priority, so

snd . head . filter (\(k,v) -> key == k) $ xs

is read as

(snd . head . filter (\(k,v) -> key == k)) xs

while your second expression is rather

snd . head . ( filter (\(k,v) -> key == k) xs )
like image 22
bereal Avatar answered Oct 16 '22 15:10

bereal