4

1:([2]) works as expected.

1:$[2] gives <interactive>:15:2: Not in scope: data constructor `:$'

I thought the $ operator parenthesizes everything after it: Haskell: difference between . (dot) and $ (dollar sign)

What is going on?

Aadit M Shah
  • 72,912
  • 30
  • 168
  • 299
ssh
  • 195
  • 1
  • 11

3 Answers3

10

You put $ between a function and a value, and it applies the function to the value.

1: isn't a function, but (1:) is, so you can do (1:) $ [2] but not 1: $ [2].

(The error you got was because without spaces, the compiler thinks :$ is one thing, not two, and operators starting with : are data constructors, just like functions starting with capitals are data constructors.)

AndrewC
  • 32,300
  • 7
  • 79
  • 115
  • Thank you for your answer, and explanation of the error message. Can you explain why `:1` is not a function? If `1:[2]` gives `[1,2]`, that means `:` is `: :: a -> [a] -> [a]`. Through currying `1:` would give `[a] -> [a]` which is a function. Even if this is incorrect, how did `()` turn it into a function? – ssh Mar 13 '15 at 18:04
  • 1
    It's called an operator section, and it's a form of partial application. Operators take two arguments, but if you supply one of them and put it in brackets the compiler sees it as a function of the one remaining argument, and you can do whatever you can normally do with a function. Examples: `(+7)` is a function that adds seven, `("Hi, "++)` adds at the front of a string, and `(' ':)` puts a space at the front of a string. – AndrewC Mar 14 '15 at 11:12
  • 1
    Thank you very much for the term. I found more information here: https://wiki.haskell.org/Section_of_an_infix_operator – ssh Mar 16 '15 at 14:45
9

The $ operator is not syntax, it's just a normal function like every other. When you write

1 :$ [2]

The first problem the compiler sees is that :$ appears as its own operator (consider + + versus ++, these are very different things), but :$ is not defined anywhere.

If you were to write

1 : $ [2]

Then the compiler doesn't understand what to do since you have two operators right next to each other, this isn't allowed, just as 1 + * 2 isn't allowed. These expressions simply don't make any sense. The $ operator is actually just defined as

f $ x = f x

But it has a low precedence, like Please Excuse My Dear Aunt Sally for arithmetic operator precedence, so that you can chain operations more easily. It does not actually insert parentheses into an expression.

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
bheklilr
  • 53,530
  • 6
  • 107
  • 163
  • I think this answer deserves more credit than mine, but so far only one other person has joined with my sentiment. – AndrewC Mar 13 '15 at 16:00
  • @AndrewC Your answer was still good, you got it posted first, and you mentioned operator sections, something I failed to. It's not like I mind the rep, at this point I don't get any more privileges, and [we're pretty closely matched on the haskell tag anyway](http://data.stackexchange.com/stackoverflow/query/45578/top-100-users-in-a-given-tag) =P – bheklilr Mar 13 '15 at 16:05
  • Thank you very much for your explanation. I learned many new things today. – ssh Mar 13 '15 at 17:58
6

$ doesn't literally place parentheses around arbitrary code, but changes the order in which functions are evaluated (like parentheses do, too).

mkrieger1
  • 19,194
  • 5
  • 54
  • 65