2

I'm writing a program in Haskell, and it involves a lot of parentheses. So to clear up that ugly mess, I use the $ operator a couple of times to make it easier to read. For example:

longFunc arg1 (anotherFunc (yetAnotherFunc arg2))

is replaced by

longFunc arg1 $ anotherFunc $ yetAnotherFunc arg2

But when I compile my program using GHCi I get a message saying:

MyFile.hs:18:18: error:
    parse error on input ‘$’
    Perhaps you intended to use TemplateHaskell
Failed, modules loaded: none.

Here's lines 16-18:

isDigit :: Char -> Bool
isDigit c =
  c `elem` $ ['0'..'9'] ++ "."

I was confused because I have used the $ operator several times (with the same compiler) like this:

main = putStrLn $ show 42

So I typed that code into my file as a test, deleted the other $ occurrences, and loaded it up.

And it worked!

Can someone please tell me what's going on?

  • Please tell us what line 18 is when it generates the error. – A. R. Apr 15 '20 at 12:58
  • Line 18 is pretty much the same thing as my example with the functions that are called with `$` instead of parentheses – InfiniteDonuts Apr 15 '20 at 13:01
  • But the error is on line 18, and not somewhere else. _Something_ is clearly different about that line. There are places where `($)` is not allowed, or may not do what you expect, e.g. on the left of an assignment. – A. R. Apr 15 '20 at 13:03
  • There, I added lines 16-18 in the question – InfiniteDonuts Apr 15 '20 at 13:07

1 Answers1

7

You can't use ($) immediately after another infix operator. Line 18:

c `elem` $ ['0'..'9'] ++ "."

needs to be rewritten as one of the following options:

  1. Keep the parentheses as original:

    c `elem` (['0'..'9'] ++ "."])
    
  2. Apply ($) to a slice of elem:

    (c `elem`) $ ['0'..'9'] ++ "."
    
  3. Convert the call to elem to a prefix call:

    elem c $ ['0'..'9'] ++ "."
    

I recommend option 3. Consecutive infix operators (in this case `elem` and $) do not have a well-defined priority and confuse the parser. The general rule of thumb is that an infix operator must always have a complete expression on each side. c `elem` is not a complete expression, so it is not allowed on the left of $. Similarly, $ ['0'..'9'] ++ "." is not a complete expression, so it is not allowed to be the right side of `elem`.

A. R.
  • 2,031
  • 13
  • 27