@@ -45,17 +45,25 @@ changes cfg m = fmap (formatSignatureDecl cfg m) (topLevelFunctionSignatures m)
4545topLevelFunctionSignatures :: Module -> [Located SignatureDecl ]
4646topLevelFunctionSignatures = queryModule @ (Located (HsDecl GhcPs )) \ case
4747 L pos (SigD _ (TypeSig _ [name] (HsWC _ (HsIB _ (L _ funTy@ (HsFunTy _ _ _ )))))) ->
48- [L pos $ MkSignatureDecl name (listParameters funTy)]
48+ [L pos $ MkSignatureDecl name (listParameters funTy) [] ]
49+ L pos (SigD _ (TypeSig _ [name] (HsWC _ (HsIB _ (L _ (HsQualTy _ (L _ contexts) (L _ funTy))))))) ->
50+ [L pos $ MkSignatureDecl name (listParameters funTy) (contexts >>= listContexts)]
4951 _ -> []
5052
5153listParameters :: HsType GhcPs -> [Located RdrName ]
5254listParameters (HsFunTy _ (L _ arg2) (L _ arg3)) = listParameters arg2 <> listParameters arg3
5355listParameters (HsTyVar _ _promotionFlag name) = [name]
5456listParameters _ = []
5557
58+ listContexts :: Located (HsType GhcPs ) -> [Located RdrName ]
59+ listContexts (L _ (HsTyVar _ _ name)) = [name]
60+ listContexts (L _ (HsAppTy _ arg1 arg2)) = listContexts arg1 <> listContexts arg2
61+ listContexts _ = []
62+
5663data SignatureDecl = MkSignatureDecl
5764 { sigName :: Located RdrName
5865 , sigParameters :: [Located RdrName ]
66+ , sigConstraints :: [Located RdrName ]
5967 }
6068
6169formatSignatureDecl :: Config -> Module -> Located SignatureDecl -> ChangeLine
@@ -74,20 +82,54 @@ printDecl Config{..} m MkSignatureDecl{..} = runPrinter_ printerConfig [] m do
7482 printRemainingLines
7583 where
7684
85+ ----------------------------------------------------------------------------------------
86+
7787 printFirstLine =
7888 putRdrName sigName >> space >> putText " ::" >> newline
7989
90+ ----------------------------------------------------------------------------------------
91+
8092 printSecondLine =
81- spaces 5 >> (putRdrName $ head sigParameters) >> newline
93+ if hasConstraints then printConstraints
94+ else printFirstParameter
95+
96+ printConstraints =
97+ spaces 5 >> putText " ("
98+ >> (traverse (\ ctr -> printConstraint ctr >> putText " , " ) (init groupConstraints))
99+ >> (printConstraint $ last groupConstraints)
100+ >> putText " )" >> newline
101+
102+ groupConstraints = zip (dropEvery sigConstraints 2 ) (dropEvery (tail sigConstraints) 2 )
103+
104+ printConstraint (tc, tp) = putRdrName tc >> space >> putRdrName tp
105+
106+ printFirstParameter =
107+ spaces 5 >> (putRdrName $ head sigParameters) >> newline
108+
109+ ----------------------------------------------------------------------------------------
82110
83111 printRemainingLines =
84- traverse printRemainingLine (tail sigParameters)
112+ if hasConstraints then
113+ printRemainingLine " =>" (head sigParameters)
114+ >> traverse (printRemainingLine " ->" ) (tail sigParameters)
115+ else
116+ traverse (printRemainingLine " ->" ) (tail sigParameters)
117+
118+ printRemainingLine prefix parameter =
119+ spaces 2 >> putText prefix >> space >> (putRdrName parameter) >> newline
85120
86- printRemainingLine parameter =
87- spaces 2 >> putText " ->" >> space >> (putRdrName parameter) >> newline
121+ ----------------------------------------------------------------------------------------
88122
89123 printerConfig = PrinterConfig
90124 { columns = case cMaxColumns of
91125 NoMaxColumns -> Nothing
92126 MaxColumns n -> Just n
93127 }
128+
129+ hasConstraints = not $ null sigConstraints
130+
131+ -- 99 problems :)
132+ dropEvery :: [a ] -> Int -> [a ]
133+ dropEvery xs n
134+ | length xs < n = xs
135+ | otherwise = take (n- 1 ) xs ++ dropEvery (drop n xs) n
0 commit comments