@@ -14,6 +14,7 @@ import BasicTypes (Fixity (..), SourceText (NoSourceText), compareFixity, defaul
1414import Data.Function (on)
1515import Data.List
1616import Data.Maybe (fromMaybe, mapMaybe)
17+import Data.Ord (Down (Down), comparing)
1718import GHC
1819import OccName (mkVarOcc)
1920import RdrName (mkRdrUnqual)
@@ -108,7 +109,7 @@ buildFixityMap getOpName opTree =
108109 . zip [0 ..]
109110 . groupBy (doubleWithinEps 0.00001 `on` snd)
110111 . (overrides ++)
111− . avgScores
112+ . modeScores
112113 $ score opTree
113114 where
114115 -- Add a special case for ($), since it is pretty unlikely for someone
@@ -141,18 +142,25 @@ buildFixityMap getOpName opTree =
141142 | otherwise =
142143 2 -- otherwise, assign a high score.
143144 return $ (opName, s) : score r
144− avgScores :: [(RdrName, Double)] -> [(RdrName, Double)]
145− avgScores =
145+ -- Pick the most common score per 'RdrName'.
146+ modeScores :: [(RdrName, Double)] -> [(RdrName, Double)]
147+ modeScores =
146148 sortOn snd
147149 . mapMaybe
148150 ( \case
149151 [] -> Nothing
150− xs@((n, _) : _) -> Just (n, avg $ map snd xs)
152+ xs@((n, _) : _) -> Just (n, mode $ map snd xs)
151153 )
152154 . groupBy ((==) `on` fst)
153155 . sort
154− avg :: [Double] -> Double
155− avg i = sum i / fromIntegral (length i)
156+ -- Return the most common number, leaning to the smaller
157+ -- one in case of a tie.
158+ mode :: [Double] -> Double
159+ mode =
160+ head
161+ . minimumBy (comparing (Down . length))
162+ . groupBy (doubleWithinEps 0.0001)
163+ . sort
156164 -- The start column of the rightmost operator.
157165 maxCol = go opTree
158166 where