Template Haskell-generated rewrite rule contains redundant parenthesis (that makes the rule be rejected)
Summary
I am trying to generate some rewrite rules with Template Haskell, and the rule that is generated contains redundant parenthesis. This would not be a problem, if the rule would not be rejected because of it.
Steps to reproduce
Here is a complete program that triggers the bug. (It is a silly rule, but it is enough to illustrate the issue)
{-# LANGUAGE TemplateHaskell #-}
module AModule where
import Language.Haskell.TH.Syntax
rejectedRule :: [Dec]
rejectedRule = [PragmaD $ RuleP "rejected-rule" Nothing foralld lhs rhs AllPhases]
where
foralld :: [RuleBndr]
foralld = [RuleVar $ mkName "x", RuleVar $ mkName "y"]
lhs :: Exp
lhs = AppE (AppE (VarE $ mkName "foo") (VarE $ mkName "x")) (VarE $ mkName "y")
rhs :: Exp
rhs = AppE (AppE (VarE $ mkName "foo") (VarE $ mkName "y")) (VarE $ mkName "x")
{-# LANGUAGE TemplateHaskell #-}
module Main where
import AModule
import Language.Haskell.TH.Syntax
$(return rejectedRule)
main = putStrLn "hello"
Expected behavior
What do you expect the reproducer described above to do?
I want it to emit this rule
{-# RULES "rejected-rule" forall x y. foo x y = foo y x #-}
but it emits this rule
{-# RULES "rejected-rule" forall x y. (foo x) y = (foo y) x #-}
And then throws this error
examples/average/Main.hs:50:2: error:
Rule "rejected-rule":
Illegal expression: (foo x)
in left-hand side: (foo x) y
LHS must be of form (f e1 .. en) where f is not forall'd
|
50 | $(return rejectedRule)
- GHC version used:
I am using GHC 9.2.8, but I found a stackoverflow thread that mentioned the issue a couple of years ago, so I think it's been around for a while.
Optional:
- Operating System: Ubuntu 22.10