Reproduce
Consider the following test.cf file:
OpEq. Op ::= "=" ;
opEq. Op ::= "~" ;
define opEq = OpEq ;
Run bnfc --haskell -d -m test.cf && make:
[1 of 7] Compiling Test.Abs ( Test/Abs.hs, Test/Abs.o )
Test/Abs.hs:13:8: error: [GHC-71614]
A lambda requires at least one parameter
|
13 | opEq = \ -> OpEq
| ^^^^^^^^^
Motivation
Defining labels without argument can be useful when supporting both ASCII and Unicode keywords. For example, consider the following example:
entrypoints Exp ;
EInt. Exp1 ::= Integer ;
EEq. Exp ::= Exp1 EqOp Exp1 ;
coercions Exp 1 ;
OpEq. EqOp ::= "==" ;
OpNEq. EqOp ::= "/=" ;
Now we would like to also support operators ≡ and ≠. Of course we can make it by defining tokens:
OpEq. EqOp ::= TokEq ;
OpNEq. EqOp ::= TokNEq ;
token TokEq ({"=="} | '≡') ;
token TokNEq ({"/="} | '≠') ;
But we will have to do an unnecessary matching on TokEq and TokNEq. With define, we can write something like:
OpEq. EqOp ::= "==" ;
OpNEq. EqOp ::= "/=" ;
opEqUnicode. EqOp ::= "≡" ;
define opEqUnicode = OpEq ;
opNEqUnicode. EqOp ::= "≠" ;
define opNEqUnicode = OpNEq ;
And the original AST remains the same.
Note
This example works correctly on other backends.
Currently, the Haskell and Haskell-GADT backends always generate a \ and -> for define rules, even there is no argument. (As a coincidence, it works with --functor because there is an extra argument for position.)
Thanks @loki259 for inspiration.
Reproduce
Consider the following
test.cffile:Run
bnfc --haskell -d -m test.cf && make:Motivation
Defining labels without argument can be useful when supporting both ASCII and Unicode keywords. For example, consider the following example:
Now we would like to also support operators
≡and≠. Of course we can make it by defining tokens:But we will have to do an unnecessary matching on
TokEqandTokNEq. Withdefine, we can write something like:And the original AST remains the same.
Note
This example works correctly on other backends.
Currently, the Haskell and Haskell-GADT backends always generate a
\and->fordefinerules, even there is no argument. (As a coincidence, it works with--functorbecause there is an extra argument for position.)Thanks @loki259 for inspiration.