2

I have a condition in my Hamlet template that looks like this:

    $if (&&) (index == 0) (row == 0)

which works fine. If I try to re-write this as the more natural

    $if (index == 0) && (row == 0)

or

    $if ((index == 0) && (row == 0))

then it doesn’t parse. The error message is:

Exception when trying to run compile-time code:

unexpected "&"

expecting ")"

This is puzzling; does it support some binary operators but not others?

What are the rules governing what kinds of expressions can be used in an $if statement in Hamlet?

Timwi
  • 65,159
  • 33
  • 165
  • 230

1 Answers1

1

Indeed I don't see that this is defined in the Yesod book or in the API docs.

Your best bet is to read the source, e.g. https://github.com/yesodweb/shakespeare/blob/master/hamlet/Text/Hamlet/Parse.hs#L458

I think the item directly after $if comes from parseDeref https://github.com/yesodweb/shakespeare/blob/master/shakespeare/Text/Shakespeare/Base.hs#L96

indeed your observation can be isolated (type this in ghci):

import Text.Shakespeare.Base
import Test.Parsec

parse parseDeref "source" "(a && b)"

    Left "source" (line 1, column 4):
    unexpected "&"
    expecting ")"

parse parseDeref "source" "(&&) a b"

    Right (DerefBranch (DerefBranch (DerefIdent (Ident "&&")) (DerefIdent (Ident "a"))) (DerefIdent (Ident "b")))

Ultimately, the parser calls Data.Char.isSymbol, and to my surprise,

isSymbol '='   ==> True
isSymbol '&'   ==> False
d8d0d65b3f7cf42
  • 2,597
  • 15
  • 28
  • Interesting. That’s a massive bug. `isSymbol` returns characters in the Unicode category *Symbol*. Many operators, including `&`, `/` and `?` are in the Unicode category *Punctuation* though. Thanks for digging that up. – Timwi Nov 28 '13 at 13:26
  • Links are broken. – Safron May 04 '21 at 13:53