6

How does outermost evaluation work on an application of a curried function? says:

in Haskell, whitespace is an operator: it applies the lhs function to the rhs argument.

Is it true? I can't find it in documents.

When Haskell compiler lexical analyzing a Haskell program, is a whitespace recognized as either a function application operator or a token separator?

glennsl
  • 28,186
  • 12
  • 57
  • 75
Tim
  • 1
  • 141
  • 372
  • 590
  • 11
    I think that's... not really a great way to understand it. e.g. `(f)x` has no whitespace, but still applies function `f` to argument `x`; meanwhile `f {x=y}` is not the application of function `f` to argument `{x=y}` even though there is whitespace there. So it doesn't really have very good predictive power about when a function application happens. – Daniel Wagner Jul 15 '19 at 01:10
  • @DanielWagner Those are really great examples! Do you mind if I edit them into my answer? – bradrn Jul 15 '19 at 01:16
  • 1
    @bradrn Please do! – Daniel Wagner Jul 15 '19 at 01:19
  • Related question: https://stackoverflow.com/questions/56202894/what-is-the-precedence-of-and-in-haskell/56203284#56203284 – AJF Jul 15 '19 at 10:43

2 Answers2

9

I’ve never heard anyone say that whitespace is an operator before. I suppose you could consider it to be an operator in the context of a function application, but in most contexts it is not an operator. For instance, I don’t see any way to consider whitespace as an operator in the following code sample, where whitespace is used only to separate tokens:

module Main where

x = "test 1"
y = "test 2"

main = do
    (z : zs) <- getLine
    putStrLn $ z : (x ++ y ++ zs)

It seems fairly obvious here that whitespace is acting purely as a token separator. The apparent ‘operator-ness’ in something like f x y z can be best thought of as saying that if two values are placed next to each other, the second is applied to the first. For instance, putStrLn"xxx" and putStrLn "xxx" both apply "xxx" to putStrLn; the space is completely irrelevant.

EDIT: In a comment, @DanielWagner provided two great examples. Firstly, (f)x is the same as f x, yet has no whitespace; here we see confirmation that the space is acting purely as a token separator, so can be replaced by a bracket (which also separates tokens) without any impact on the lexemes of the expression. Secondly, f {x=y} does not apply {x=y} to f, but rather uses record syntax to create a new record based on f; again, we can remove the space to get f{x=y}, which does an equally good job of separating the lexemes.

bradrn
  • 8,337
  • 2
  • 22
  • 51
  • 1
    I've seen the "whitespace operator" (which is silly) or "adjacency operator" (slightly less so) concept referred to a few times. I don't know why people seem to want an "invisible operator" to be there to explain function application. You have to do most of the job of parsing to know which token adjacencies represent this invisible operator and which do not, so it seems much more straigthforward to me to think about parsing directly to a tree of function applications, but the metaphor seems to help some people. – Ben Jul 16 '19 at 04:53
1

The white space in most cases is "function application", meaning apply the function of the right, to the argument to the left, just like the ($) operator, but it can be used to be more clear on your code, some examples:

plusOne = (1 +)

you can either do

plusOne 2

or

plusOne $ 2

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

I forgot a usefull example:

imagine you want to filter the greater than 3, but before you want to add one to each element:

filter (>3) $ map plusOne [1,2,3,4]

That will compile, but this wont:

filter (>3) map plusOne [1,2,3,4]

But in other cases, is not function application, like the other @bradrn answer or @Daniel warner comment just shows.

developer_hatch
  • 15,898
  • 3
  • 42
  • 75
  • What is wrong with the answer? Maybe some advice would help. I cannot see the error. Thanks in advance – developer_hatch Jul 15 '19 at 02:05
  • There's no error, per se. I just don't see what you're trying to say. The question is about whitespace and whether or not it's an operator, and your answer seems to be about the precedence of `$` as a function. I just don't see the connection, to be honest. Everything you say is correct; I just don't see how it applies to the OP. – Silvio Mayolo Jul 15 '19 at 02:21
  • @SilvioMayolo aaaaaah I see... I was trying to say that in some cases is function application, just like ($), I will edit though, it's not clear apparently – developer_hatch Jul 15 '19 at 02:22
  • @SilvioMayolo maybe now is clear the point I was trying to make – developer_hatch Jul 15 '19 at 02:25
  • @DamianLattenero I downvoted before you edited it — I couldn’t understand what ‘There is a synonymous for function application’ meant. I think I’ll remove my downvote now that you’ve made your answer clearer. – bradrn Jul 15 '19 at 02:46
  • @bradrn every help for a better answer is appreciated, even a downvote with good arguments (Y). thanks a lot – developer_hatch Jul 15 '19 at 02:50
  • 1
    @DamianLattenero You’re welcome! I’m impressed you even asked about the downvotes; because of that, your answer now is much better than it was. – bradrn Jul 15 '19 at 02:51