unbound-0.2: Unbound/Util.hs
module Unbound.Util where
import Data.Maybe (catMaybes)
import Data.Monoid
import qualified Data.Foldable as F
import qualified Data.Set as S
import qualified Data.Map as M
------------------------------------------------------------
-- Convenient Monoid syntax
------------------------------------------------------------
(<>) :: Monoid m => m -> m -> m
(<>) = mappend
------------------------------------------------------------
-- Collections
------------------------------------------------------------
-- | Collections are foldable types that support empty, singleton,
-- union, and map operations. The result of a free variable
-- calculation may be any collection. Instances are provided for
-- lists and sets.
class F.Foldable f => Collection f where
emptyC :: f a
singleton :: a -> f a
union :: Ord a => f a -> f a -> f a
cmap :: (Ord a, Ord b) => (a -> b) -> f a -> f b
-- | Combine a list of containers into one.
unions :: (Ord a, Collection f) => [f a] -> f a
unions = foldr union emptyC
-- | Create a collection from a list of elements.
fromList :: (Ord a, Collection f) => [a] -> f a
fromList = unions . map singleton
-- | Remove the @Nothing@s from a collection.
filterC :: (Collection f, Ord a) => f (Maybe a) -> f a
filterC = fromList . catMaybes . F.toList
-- | Lists are containers under concatenation. Lists preserve
-- ordering and multiplicity of elements.
instance Collection [] where
emptyC = []
singleton = (:[])
union = (++)
cmap = map
-- | A simple representation of multisets.
newtype Multiset a = Multiset (M.Map a Int)
instance F.Foldable Multiset where
fold (Multiset m) = M.foldrWithKey (\a n x -> mconcat (x : replicate n a)) mempty m
-- | Multisets are containers which preserve multiplicity but not
-- ordering.
instance Collection Multiset where
emptyC = Multiset M.empty
singleton = Multiset . flip M.singleton 1
(Multiset m1) `union` (Multiset m2) = Multiset $ M.unionWith (+) m1 m2
cmap f (Multiset m) = Multiset $ M.mapKeys f m
-- | Sets are containers under union, which preserve only occurrence,
-- not multiplicity or ordering.
instance Collection S.Set where
emptyC = S.empty
singleton = S.singleton
union = S.union
cmap = S.map