{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ConstrainedClassMethods #-} module Data.Set.Class where import Prelude hiding (Foldable (..), filter) import Control.Monad (guard) import qualified Data.Foldable as F import Data.Function (on) import qualified Data.Maybe as List (catMaybes, mapMaybe) import Data.Monoid import qualified Data.Set as C import qualified Data.IntSet as I import Util class Set set where type Elem set empty :: set fold :: Monoid (Elem set) => set -> Elem set foldMap :: Monoid a => (Elem set -> a) -> set -> a foldr :: (Elem set -> a -> a) -> a -> set -> a foldl :: (a -> Elem set -> a) -> a -> set -> a toList :: set -> [Elem set] length :: set -> Int size :: set -> Int null :: set -> Bool mapMaybe :: (Elem set -> Maybe (Elem set)) -> set -> set mapEither :: (Elem set -> Either (Elem set) (Elem set)) -> set -> (set, set) filter :: (Elem set -> Bool) -> set -> set member :: Elem set -> set -> Bool fromList :: [Elem set] -> set insert, delete :: Elem set -> set -> set singleton :: Elem set -> set union, intersection, difference, symmetricDifference :: set -> set -> set (⊆) :: set -> set -> Bool fold = foldMap id foldMap f = foldr ((<>) . f) mempty foldr f z = flip appEndo z . foldMap (Endo . f) foldl f z = flip appEndo z . getDual . foldMap (Dual . Endo . flip f) toList = foldr (:) [] length = F.length . toList size = F.length . toList null = (==) 0 . size fromList = F.foldr insert empty member = (⊆) . singleton (⊆) = null ∘∘ difference union = fromList ∘∘ (++) `on` toList difference = foldr delete symmetricDifference = \ a b -> difference a b `union` difference b a intersection = \ a b -> union a b `difference` symmetricDifference a b mapMaybe f = fromList . List.mapMaybe f . toList mapEither f = (,) <$> mapMaybe (either Just (pure Nothing) . f) <*> mapMaybe (either (pure Nothing) Just . f) filter p = mapMaybe ((<$) <*> guard . p) {-# DEPRECATED length "use `size`" #-} instance Ord a => Set (C.Set a) where type Elem (C.Set a) = a empty = C.empty fold = F.fold foldMap = F.foldMap foldr = C.foldr foldl = C.foldl toList = C.toList length = C.size size = C.size null = C.null mapMaybe f = C.fromAscList . List.catMaybes . C.toAscList . C.map f filter = C.filter member = C.member fromList = C.fromList insert = C.insert delete = C.delete singleton = C.singleton union = C.union intersection = C.intersection difference = C.difference (⊆) = C.isSubsetOf instance Set I.IntSet where type Elem I.IntSet = Int empty = I.empty foldr = I.foldr foldl = I.foldl toList = I.toList length = I.size size = I.size null = I.null filter = I.filter member = I.member fromList = I.fromList insert = I.insert delete = I.delete singleton = I.singleton union = I.union intersection = I.intersection difference = I.difference (⊆) = I.isSubsetOf