-- | -- A monoid that combines according to priorities, allowing some values to take precedence over others. module Web.Route.Invertible.Monoid.Prioritized ( Prioritized(..) ) where -- |A trival monoid allowing each item to be given a priority when combining. data Prioritized a = Prioritized { priority :: !Int -- ^ The priority this value, where larger numeric values have higher priority and take precedence over lower priorities. , prioritized :: !a -- ^ The prioritized value. } deriving (Eq, Show) instance Functor Prioritized where fmap f (Prioritized p x) = Prioritized p (f x) instance Semigroup a => Semigroup (Prioritized a) where a1@(Prioritized p1 x1) <> a2@(Prioritized p2 x2) = case compare p1 p2 of LT -> a2 GT -> a1 EQ -> Prioritized p1 (x1 <> x2) -- |Combining two values with the same priority combines the values, otherwise it discards the value with a smaller priority. instance Monoid a => Monoid (Prioritized a) where mempty = Prioritized minBound mempty mappend a1@(Prioritized p1 x1) a2@(Prioritized p2 x2) = case compare p1 p2 of LT -> a2 GT -> a1 EQ -> Prioritized p1 (mappend x1 x2)