#4430: Better support for resolving infix expressions in template haskell
---------------------------------+------------------------------------------
Reporter: reinerp | Owner: igloo
Type: feature request | Status: patch
Priority: normal | Milestone: 7.4.1
Component: Template Haskell | Version: 6.12.3
Keywords: | Testcase:
Blockedby: | Difficulty:
Os: Unknown/Multiple | Blocking:
Architecture: Unknown/Multiple | Failure: None/Unknown
---------------------------------+------------------------------------------
Comment(by reinerp):
Sorry, I guess I didn't explain my thoughts clearly. I'll give it another
shot.
== What is the special case ==
The special case is not explicit, but it's there. In Convert.cvtl, compare
the cases for {{{InfixE (Just x) s (Just y)}}} and {{{InfixE Nothing s
(Just y)}}} (this is around line 488). We produce the following output:
{{{
InfixE (Just x) s (Just y) ---> HsPar (OpApp (HsPar x) s (HsPar y))
InfixE Nothing s (Just y) ---> HsPar (SectionR s y)
}}}
Note that the former puts parentheses around the {{{y}}}, whereas the
latter doesn't. This means that when the renamer runs, the {{{OpApp}}}s
coming from {{{y}}} will meet the {{{SectionR}}} in the second case, but
they won't meet the {{{OpApp}}} in the first case. That is:
{{{
InfixE (Just x) s (Just (UInfix y op z))
---> HsPar (OpApp
(HsPar x)
s
(HsPar (OpApp y op z)))
(the OpApps don't meet, so they aren't reassociated)
InfixE Nothing s (Just (UInfix y op z))
---> HsPar (SectionR
s
(OpApp y op z))
(the OpApp meets the SectionR, so the renamer will throw an error if
@op@ is left-infix)
}}}
Of course, the same applies the the {{{SectionL}}} case.
== Option 1, a summary ==
For comparison with the next section, here is what Option 1 does:
{{{
data Exp =
...
| InfixE (Maybe Exp) Exp (Maybe Exp)
| UInfixE Exp Exp Exp
...
}}}
and {{{Convert.cvtl}}} does this:
{{{
InfixE (Just x) s (Just y) ---> HsPar (OpApp (HsPar x) s (HsPar y))
InfixE Nothing s (Just y) ---> HsPar (SectionR s y )
InfixE (Just x) s Nothing ---> HsPar (SectionL x s )
UInfixE x s y ---> (OpApp x s y )
}}}
== What Option 2 would look like ==
In Option 2, we would have
{{{
data Exp =
...
| InfixE (Maybe Exp) Exp (Maybe Exp)
| UInfixE (Maybe Exp) Exp (Maybe Exp)
...
}}}
and the relevant parts of {{{Convert.cvtl}}} would be
{{{
InfixE (Just x) s (Just y) ---> HsPar (OpApp (HsPar x) s (HsPar y))
InfixE Nothing s (Just y) ---> HsPar (SectionR s (HsPar y))
InfixE (Just x) s Nothing ---> HsPar (SectionL (HsPar x) s )
UInfixE (Just x) s (Just y) ---> (OpApp x s y )
UInfixE Nothing s (Just y) ---> (SectionR s y )
UInfixE (Just x) s Nothing ---> (SectionL x s )
}}}
== Why option 1 is surprising ==
Perhaps the comment I wrote was too strongly worded in saying that there
was a special case. But Option 1 is still surprising.
Consider:
{{{
-- with option 1
InfixE (Just x) s (Just y) -- doesn't care if x and y are
UInfixE's, i.e. no fixity errors, no reassociating
InfixE Nothing s (Just y) -- if y is a UInfixE with a left-infix
operator, the renamer will throw a fixity error
InfixE Nothing s (Just (Parens y)) -- doesn't care if y is a UInfixE
-- with option 2
InfixE (Just x) s (Just y) -- doesn't care if x and y are
UInfixE's
InfixE Nothing s (Just y) -- doesn't care if y is a UInfixE
UInfixE Nothing s (Just y) -- if y is a UInfixE with a left-infix
operator, the renamer will throw a fixity error
}}}
I find option 1 surprising, because I don't expect {{{InfixE}}} to "look
inside" its argument. And for non-section uses of {{{InfixE}}}, it
doesn't, but for sections it does! (I can't find a better description for
what happens in the above examples than "doesn't care" versus "looks
inside", which is unfortunate, and perhaps a source of the confusion. I
hope it's clear what I mean.)
Sorry for dragging things out so long.
Reiner
--
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/4430#comment:24>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs