{-# LANGUAGE UnboxedTuples #-}moduleData.TrieSet(-- * Set typeTSet,-- * Operators(\\),-- * Querynull,size,member,notMember,isSubsetOf,isProperSubsetOf,-- * Constructionempty,singleton,insert,delete,-- * Combineunion,symmetricDifference,intersection,difference,-- * Filterfilter,partition,split,splitMember,-- * Mapmap,mapMonotonic,-- * Foldfoldl,foldr,-- * Min/MaxfindMin,findMax,deleteMin,deleteMax,deleteFindMin,deleteFindMax,minView,maxView,-- * Conversion-- ** MapmapSet,-- ** Listelems,toList,fromList,-- ** Ordered liststoAscList,fromAscList,fromDistinctAscList)whereimportData.TrieMap.ClassimportData.TrieMap.Class.Instances()importData.TrieMap.TrieKeyimportData.TrieMap.Representation.ClassimportData.TrieMap.SizedimportData.TrieMap.UtilsimportControl.Monad.EndsimportData.MaybeimportqualifiedData.FoldableasFimportData.Monoid(Monoid(..))importGHC.ExtsimportPreludehiding(foldr,foldl,map,filter,null)instanceTKeya=>Eq(TSeta)wheres1==s2=sizes1==sizes2&&s1`isSubsetOf`s2instance(TKeya,Orda)=>Ord(TSeta)wheres1`compare`s2=elemss1`compare`elemss2instance(TKeya,Showa)=>Show(TSeta)whereshows="fromList "++show(elemss)instanceTKeya=>Monoid(TSeta)wheremempty=emptymappend=union-- | The empty 'TSet'.empty::TKeya=>TSetaempty=TSetemptyM-- | Insert an element into the 'TSet'.insert::TKeya=>a->TSeta->TSetainserta(TSets)=TSet(insertWithM(const(Elema))(toRepa)(Elema)s)-- | Delete an element from the 'TSet'.delete::TKeya=>a->TSeta->TSetadeletea(TSets)=TSet(searchMC(toRepa)sclearM(constclearM))-- | /O(1)/. Create a singleton set.singleton::TKeya=>a->TSetasingletona=TSet(singletonM(toRepa)(Elema))-- | The union of two 'TSet's, preferring the first set when-- equal elements are encountered.union::TKeya=>TSeta->TSeta->TSetaTSets1`union`TSets2=TSet(unionM(const.Just)s1s2)-- | The symmetric difference of two 'TSet's.symmetricDifference::TKeya=>TSeta->TSeta->TSetaTSets1`symmetricDifference`TSets2=TSet(unionM(\__->Nothing)s1s2)-- | Difference of two 'TSet's.difference::TKeya=>TSeta->TSeta->TSetaTSets1`difference`TSets2=TSet(diffM(\__->Nothing)s1s2)-- | Intersection of two 'TSet's. Elements of the result come from the first set.intersection::TKeya=>TSeta->TSeta->TSetaTSets1`intersection`TSets2=TSet(isectM(const.Just)s1s2)-- | Filter all elements that satisfy the predicate.filter::TKeya=>(a->Bool)->TSeta->TSetafilterp(TSets)=TSet(mapMaybeM(\(Elema)->ifpathenJust(Elema)elseNothing)s)-- | Partition the set into two sets, one with all elements that satisfy-- the predicate and one with all elements that don't satisfy the predicate.-- See also 'split'.partition::TKeya=>(a->Bool)->TSeta->(TSeta,TSeta)partitionp(TSets)=casemapEitherMfsof(#s1,s2#)->(TSets1,TSets2)wherefe@(Elema)|pa=(#Juste,Nothing#)|otherwise=(#Nothing,Juste#)-- | The expression (@'split' x set@) is a pair @(set1,set2)@-- where @set1@ comprises the elements of @set@ less than @x@ and @set2@-- comprises the elements of @set@ greater than @x@.split::TKeya=>a->TSeta->(TSeta,TSeta)splitas=casesplitMemberasof(sL,_,sR)->(sL,sR)-- | Performs a 'split' but also returns whether the pivot-- element was found in the original set.splitMember::TKeya=>a->TSeta->(TSeta,Bool,TSeta)splitMembera(TSets)=searchMC(toRepa)snomatchmatchwherenomatchhole=(TSet(beforeMhole),False,TSet(afterMhole))match_hole=(TSet(beforeMhole),True,TSet(afterMhole))-- |-- @'map' f s@ is the set obtained by applying @f@ to each element of @s@.-- -- It's worth noting that the size of the result may be smaller if,-- for some @(x,y)@, @x \/= y && f x == f y@map::(TKeya,TKeyb)=>(a->b)->TSeta->TSetbmapfs=fromList[fx|x<-elemss]-- | -- @'mapMonotonic' f s == 'map' f s@, but works only when @f@ is monotonic.-- /The precondition is not checked./-- Semi-formally, we have:-- -- > and [x < y ==> f x < f y | x <- ls, y <- ls] -- > ==> mapMonotonic f s == map f s-- > where ls = toList smapMonotonic::(TKeya,TKeyb)=>(a->b)->TSeta->TSetbmapMonotonicfs=fromAscList[fx|x<-toAscLists]-- | Post-order fold.foldr::TKeya=>(a->b->b)->b->TSeta->bfoldrfz(TSets)=F.foldr(flip$F.foldrf)zs-- | Pre-order fold.foldl::TKeyb=>(a->b->a)->a->TSetb->afoldlfz(TSets)=F.foldl(F.foldlf)zs-- | The minimal element of the set.findMin::TKeya=>TSeta->afindMin=fst.deleteFindMin-- | The maximal element of the set.findMax::TKeya=>TSeta->afindMax=fst.deleteFindMax-- | Delete the minimal element.deleteMin::TKeya=>TSeta->TSetadeleteMins=maybessnd(minViews)-- | Delete the maximal element.deleteMax::TKeya=>TSeta->TSetadeleteMaxs=maybessnd(maxViews)-- | Delete and find the minimal element.-- -- > 'deleteFindMin' set = ('findMin' set, 'deleteMin' set)deleteFindMin::TKeya=>TSeta->(a,TSeta)deleteFindMin=fromJust.minView-- | Delete and find the maximal element.-- -- > 'deleteFindMax' set = ('findMax' set, 'deleteMax' set)deleteFindMax::TKeya=>TSeta->(a,TSeta)deleteFindMax=fromJust.maxView-- | Retrieves the minimal key of the set, and the set-- stripped of that element, or 'Nothing' if passed an empty set.minView::TKeya=>TSeta->Maybe(a,TSeta)minView(TSets)=casegetFirst(extractHoleMs)ofNothing->NothingJust(Elema,hole)->Just(a,TSet(afterMhole))-- | Retrieves the maximal key of the set, and the set-- stripped of that element, or 'Nothing' if passed an empty set.maxView::TKeya=>TSeta->Maybe(a,TSeta)maxView(TSets)=casegetLast(extractHoleMs)ofNothing->NothingJust(Elema,hole)->Just(a,TSet(beforeMhole)){-# INLINE elems #-}-- | See 'toAscList'.elems::TKeya=>TSeta->[a]elems=toAscList{-# INLINE toList #-}-- | See 'toAscList'.toList::TKeya=>TSeta->[a]toList=toAscList{-# INLINE toAscList #-}-- | Convert the set to an ascending list of elements.toAscList::TKeya=>TSeta->[a]toAscLists=build(\cn->foldrcns)-- | Create a set from a list of elements.fromList::TKeya=>[a]->TSetafromListxs=TSet(fromListMconst[(toRepx,Elemx)|x<-xs])-- | Build a set from an ascending list in linear time.-- /The precondition (input list is ascending) is not checked./fromAscList::TKeya=>[a]->TSetafromAscListxs=TSet(fromAscListMconst[(toRepx,Elemx)|x<-xs])-- | /O(n)/. Build a set from an ascending list of distinct elements in linear time.-- /The precondition (input list is strictly ascending) is not checked./fromDistinctAscList::TKeya=>[a]->TSetafromDistinctAscListxs=TSet(fromDistAscListM[(toRepx,Elemx)|x<-xs])-- | /O(1)/. Is this the empty set?null::TKeya=>TSeta->Boolnull(TSets)=nullMs-- | /O(1)/. The number of elements in the set.size::TKeya=>TSeta->Intsize(TSets)=getSizes-- | Is the element in the set?member::TKeya=>a->TSeta->Boolmembera(TSets)=option(lookupM(toRepa)s)False(constTrue)-- | Is the element not in the set?notMember::TKeya=>a->TSeta->BoolnotMember=not.:member-- | Is this a subset? @(s1 `isSubsetOf` s2)@ tells whether @s1@ is a subset of @s2@.isSubsetOf::TKeya=>TSeta->TSeta->BoolTSets1`isSubsetOf`TSets2=isSubmapM(\__->True)s1s2-- | Is this a proper subset? (ie. a subset but not equal).isProperSubsetOf::TKeya=>TSeta->TSeta->Bools1`isProperSubsetOf`s2=sizes1<sizes2&&s1`isSubsetOf`s2-- | See 'difference'.(\\)::TKeya=>TSeta->TSeta->TSeta(\\)=difference{-# INLINE [1] mapSet #-}-- | Generate a 'TMap' by mapping on the elements of a 'TSet'.mapSet::TKeya=>(a->b)->TSeta->TMapabmapSetf(TSets)=TMap(fmapM(\(Elema)->Assoca(fa))s)