| 122 | == Template Haskell Quotations and {{{UnresolvedInfixE}}} == |
| 123 | If we have a Template Haskell quote containing infix expressions, for example |
| 124 | {{{ |
| 125 | foo = [| x + y * z |] |
| 126 | }}} |
| 127 | then how will these infix expressions be represented? |
| 128 | |
| 129 | The important point is: '''the infix expressions will have already been resolved'''. (This is because GHC knows that {{{(+)}}} and {{{(*)}}} in the above example refer to the in-scope ones, so the fixities are known when the quote is constructed -- so we should certainly communicate this information.) |
| 130 | |
| 131 | The precise representation of the (already-resolved) infix expressions will depend on whether the {{{InfixE}}} constructor will be removed, as discussed in the following section. At present, we can say the following: |
| 132 | * if the {{{InfixE}}} constructor is ''not'' removed, then (already-resolved) infix expressions will be written in terms of the {{{InfixE}}} constructor, as is currently the case. |
| 133 | * if the {{{InfixE}}} constructor ''is'' removed, then infix expressions will be written in terms of unambiguous {{{UnresolvedInfixE}}} expressions (see above for discussion of when {{{UnresolvedInfixE}}} expressions are unambiguous). |
| 134 | |
| 135 | == Redundancy; should {{{InfixE}}} be removed? == |
| 136 | Because of the equivalences discussed earlier, we see that the {{{InfixE}}} constructor will be completely redundant after these changes. It is not clear to me what this means for design. The following are some options. |
| 137 | * We could remove the {{{InfixE}}} constructor. Unfortunately, this means that every TH program which generates infix expressions would have to be changed. |
| 138 | * We could modify the {{{UnresolvedInfixE}}} constructor to remove the ambiguity -- the idea being that {{{UnresolvedInfixE}}} is reserved for infix expressions which are truly ambiguous. This would involve requiring the list to be of length >=2 when we have {{{NoSection}}}, and length >=1 when we have {{{LeftSection}}} or {{{RightSection}}}. To do this the most obvious way ("unrolling" part of the list) unfortunately makes the constructors very large: |
| 139 | {{{ |
| 140 | data Exp = |
| 141 | ... |
| 142 | | UnresolvedInfixE [(Exp,Op)] Exp Op Exp Op Exp |
| 143 | | UnresolvedLeftSection Op Exp Op Exp [(Op,Exp)] |
| 144 | | UnresolvedRightSection [(Exp,Op)] Exp Op Exp Op |
| 145 | }}} |
| 146 | * We could put up with the redundancy, and perhaps write a {{{convertUnambiguousToInfixE :: Exp -> Exp}}} which converts all unambiguous {{{UnresolvedInfixE}}}s to {{{InfixE}}}s. |
| 147 | |
| 148 | == Is there a better definition of {{{UnresolvedInfixE}}}? == |
| 149 | The definition of {{{UnresolvedInfixE}}} I have given above is somewhat ugly, because it suggests an asymmetry which is not actually present. However, it manages to enforce the precise relationship that must hold between the number of operators and the number of operands -- which, for example, {{{InfixE}}} does not currently enforce. |
| 150 | |
| 151 | Is there a better definition of this constructor? |