Support “fine-grained” operator precedence
sellout opened this issue · 0 comments
I sometimes end up with long chains of operators with identical precedence. E.g., in some parser code, I have
infixr 3 >~< -- run two parsers with whitespace between them
infixr 3 |~| -- run two parsers with optional whitespace between them
infixr 3 <~> -- run two parsers without whitespace between them
They should have the same precedence, because they’re mutually associative, so that’s all good. But when Ormolu formats a chain split across multiple lines, it can get noisy
startFormTok
|~| messageTag
>~< startMessageTok
|~| name
>~< p'
|~| endMessageTok
|~| endFormTok
What I would like is for Ormolu to treat them so that required whitespace is lower precedence than optional, is lower than illegal whitespace, so I can have it formatted like
startFormTok |~| messageTag
>~< startMessageTok |~| name
>~< p' |~| endMessageTok |~| endFormTok
I think a fairly clean solution would be for the .ormolu file to parse the precedences as floating point, rather than integers. Existing .ormolu files should work as is, but I can edit it to look like
infixr 3 >~<
infixr 3.3 |~|
infixr 3.7 <~>
and get the behavior I want.
As far as working with #846, perhaps regeneration could update the integral part without affecting the fractional part, so the fine-grained relationships are preserved even if the operator precedence has shifted.
What I currently do is fill my .ormolu with lies. Using incorrect precedences like
infixr 3 >~<
infixr 4 |~|
infixr 5 <~>
gets me the behavior I want, but I have to be careful to adjust any other precedences that bump into these.