@@ -9,8 +9,9 @@ import Control.Monad
99import Control.Monad.Writer.Class (MonadWriter (.. ))
1010import Control.Monad.Error.Class (MonadError (.. ))
1111
12+ import Data.Function (on )
1213import Data.Foldable (traverse_ )
13- import Data.List (intersect )
14+ import Data.List (intersect , groupBy , sortBy )
1415import Data.Maybe (fromMaybe , mapMaybe )
1516import qualified Data.Map as M
1617
@@ -224,7 +225,7 @@ filterModule
224225 -> [DeclarationRef ]
225226 -> m Exports
226227filterModule mn exps refs = do
227- types <- foldM filterTypes M. empty refs
228+ types <- foldM filterTypes M. empty (combineTypeRefs refs)
228229 typeOps <- foldM (filterExport TyOpName getTypeOpRef exportedTypeOps) M. empty refs
229230 classes <- foldM (filterExport TyClassName getTypeClassRef exportedTypeClasses) M. empty refs
230231 values <- foldM (filterExport IdentName getValueRef exportedValues) M. empty refs
@@ -239,6 +240,18 @@ filterModule mn exps refs = do
239240
240241 where
241242
243+ -- Takes the list of exported refs, filters out any non-TypeRefs, then
244+ -- combines any duplicate type exports to ensure that all constructors
245+ -- listed for the type are covered. Without this, only the data constructor
246+ -- listing for the last ref would be used.
247+ combineTypeRefs :: [DeclarationRef ] -> [DeclarationRef ]
248+ combineTypeRefs
249+ = fmap (uncurry TypeRef )
250+ . map (foldr1 $ \ (tc, dcs1) (_, dcs2) -> (tc, liftM2 (++) dcs1 dcs2))
251+ . groupBy ((==) `on` fst )
252+ . sortBy (compare `on` fst )
253+ . mapMaybe getTypeRef
254+
242255 filterTypes
243256 :: M. Map (ProperName 'TypeName) ([ProperName 'ConstructorName], ModuleName )
244257 -> DeclarationRef
0 commit comments