2
votes

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?

1

1 Answers

1
votes

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