+C.derive [d| instance Foldable Imports ImportOp
+ instance Collection Imports ImportOp
+ instance Map Imports ImportOp ()
+ instance Set Imports ImportOp
+ instance SortingCollection Imports ImportOp
+ |]
+
+-- |@'insert' imp@ merges @imp@ with an existing one if any.
+instance Unfoldable Imports ImportOp where
+ insert qi@(QualifiedImp {}) (Imports s) = Imports $ insert qi s
+ insert ui@(UnqualifiedImp {}) (Imports s)
+ = case find sameMod s of
+ Nothing → Imports $ insert ui s
+ Just ui' → Imports $ insert (merge ui') (delete ui' s)
+ where
+ sameMod ∷ ImportOp → Bool
+ sameMod ui'@(UnqualifiedImp {})
+ = impModule ui ≡ impModule ui'
+ sameMod _
+ = False
+
+ merge ∷ ImportOp → ImportOp
+ merge ui'
+ = case (impNames ui, impNames ui') of
+ (Nothing, _ ) → ui
+ (_ , Nothing ) → ui'
+ (Just ns, Just ns') → ui { impNames = Just (ns ⊕ ns') }
+
+ empty = Imports empty
+ singleton = Imports ∘ singleton
+
+instance Monoid Imports where
+ mempty = empty
+ mappend = insertMany
+