@@ -17,6 +17,7 @@ import GHC
1717import Ormolu.Printer.Combinators
1818import Ormolu.Printer.Meat.Common
1919import Ormolu.Utils
20+import SrcLoc (combineSrcSpans)
2021import {-# SOURCE #-} Ormolu.Printer.Meat.Declaration.Value (p_hsSplice)
2122
2223p_hsType :: HsType GhcPs -> R ()
@@ -66,13 +67,26 @@ p_hsType = \case
6667 HsSumTy NoExt xs ->
6768 parensHash . sitcc $
6869 sep (txt "| " >> breakpoint') (sitcc . located' p_hsType) xs
69− HsOpTy NoExt x op y -> do
70− located x p_hsType
71− breakpoint
72− inci $ do
73− p_rdrName op
74− space
75− located y p_hsType
70+ HsOpTy NoExt x op y -> sitcc $ do
71+ -- In the AST, type operators are right-associative instead of left-associative
72+ -- like value level operators. This makes similar constructs look inconsistent.
73+ -- Here, we shake the AST to convert right-associative tree to a left-associative
74+ -- one.
75+ case unLoc y of
76+ HsOpTy NoExt x' op' y' ->
77+ p_hsType $
78+ HsOpTy
79+ NoExt
80+ (L (combineSrcSpans (getLoc x) (getLoc x')) (HsOpTy NoExt x op x'))
81+ op'
82+ y'
83+ _ -> do
84+ located x p_hsType
85+ breakpoint
86+ inci $ do
87+ p_rdrName op
88+ space
89+ located y p_hsType
7690 HsParTy NoExt (L _ t@HsKindSig {}) ->
7791 -- NOTE Kind signatures already put parentheses around in all cases, so
7892 -- skip this layer of parentheses. The reason for this behavior is that