Skip to content

Commit 4f674f4

Browse files
authored
Merge pull request haskell#1 from obsidiansystems/non-empty-foldable
Work on NonEmptySet
2 parents 344390b + f3490fb commit 4f674f4

File tree

1 file changed

+97
-9
lines changed

1 file changed

+97
-9
lines changed

containers/src/Data/Set/Internal.hs

Lines changed: 97 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
{-# LANGUAGE PatternSynonyms #-}
1212
{-# LANGUAGE RoleAnnotations #-}
1313
{-# LANGUAGE TypeFamilies #-}
14+
{-# LANGUAGE ScopedTypeVariables #-}
1415
#endif
1516

1617
{-# OPTIONS_HADDOCK not-home #-}
@@ -147,23 +148,23 @@ module Data.Set.Internal (
147148
, lookupGE, lookupGENE
148149
, isSubsetOf, isSubsetOfNE
149150
, isProperSubsetOf, isProperSubsetOfNE
150-
, disjoint, disjointNE
151+
, disjoint, disjointNE, disjointNEX
151152

152153
-- * Construction
153154
, empty
154155
, singleton, singletonNE
155156
, insert, insertNE
156157
, delete, deleteNE
157158
, alterF
158-
, powerSet
159+
, powerSet, powerSetNE
159160

160161
-- * Combine
161162
, union, unionNE
162163
, unions
163164
, difference, differenceNE
164165
, intersection, intersectionNE
165-
, cartesianProduct
166-
, disjointUnion
166+
, cartesianProduct, cartesianProductNE
167+
, disjointUnion, disjointUnionNE, disjointUnionNEX, disjointUnionXNE
167168

168169
-- * Filter
169170
, filter, filterNE
@@ -173,7 +174,7 @@ module Data.Set.Internal (
173174
, partition, partitionNE
174175
, split, splitNE
175176
, splitMember, splitMemberNE
176-
, splitRoot
177+
, splitRoot, splitRootNE, splitNERootNE
177178

178179
-- * Indexed
179180
, lookupIndex, lookupIndexNE
@@ -185,13 +186,12 @@ module Data.Set.Internal (
185186
, splitAt, splitAtNE
186187

187188
-- * Map
188-
, map
189+
, map, mapNE
189190
, mapMonotonic, mapMonotonicNE
190191

191192
-- * Folds
192193
, foldr, foldr1
193194
, foldl, foldl1
194-
-- ** Strict folds
195195
, foldr', foldr1'
196196
, foldl', foldl1'
197197
-- ** Legacy folds
@@ -385,6 +385,47 @@ instance Foldable.Foldable Set where
385385
{-# INLINABLE product #-}
386386
#endif
387387

388+
instance Foldable.Foldable NonEmptySet where
389+
fold = goNE
390+
where goNE (Bin' 1 k _ _) = k
391+
goNE (Bin' _ k l r) = go l `mappend` (k `mappend` go r)
392+
go Tip = mempty
393+
go (NE s) = goNE s
394+
{-# INLINABLE fold #-}
395+
-- foldr f z s = foldr
396+
-- {-# INLINE foldr #-}
397+
-- foldl = foldl
398+
-- {-# INLINE foldl #-}
399+
foldMap f t = goNE t
400+
where goNE (Bin' 1 k _ _) = f k
401+
goNE (Bin' _ k l r) = go l `mappend` (f k `mappend` go r)
402+
go Tip = mempty
403+
go (NE s) = goNE s
404+
{-# INLINE foldMap #-}
405+
-- foldl' = foldl'
406+
-- {-# INLINE foldl' #-}
407+
-- foldr' = foldr'
408+
-- {-# INLINE foldr' #-}
409+
#if MIN_VERSION_base(4,8,0)
410+
length = sizeNE
411+
{-# INLINE length #-}
412+
null _ = False
413+
{-# INLINE null #-}
414+
#if MIN_VERSION_base(4,9,0)
415+
toList = NEL.toList . toListNE
416+
{-# INLINE toList #-}
417+
#endif
418+
elem x xs = elem x $ NE xs
419+
{-# INLINABLE elem #-}
420+
minimum = lookupMinNE
421+
{-# INLINE minimum #-}
422+
maximum = lookupMaxNE
423+
{-# INLINE maximum #-}
424+
-- sum = foldl' (+) 0
425+
-- {-# INLINABLE sum #-}
426+
-- product = foldl' (*) 1
427+
-- {-# INLINABLE product #-}
428+
#endif
388429

389430
#if __GLASGOW_HASKELL__
390431

@@ -798,8 +839,8 @@ alteredSet :: Ord a => a -> Set a -> AlteredSet a
798839
alteredSet x0 s0 = go x0 s0
799840
where
800841
go :: Ord a => a -> Set a -> AlteredSet a
801-
go x Tip = Inserted (singleton x)
802-
go x (Bin _ y l r) = case compare x y of
842+
go x Tip = Inserted (singleton x)
843+
go x (NE (Bin' _ y l r)) = case compare x y of
803844
LT -> case go x l of
804845
Deleted d -> Deleted (balanceR y d r)
805846
Inserted i -> Inserted (balanceL y i r)
@@ -1170,6 +1211,9 @@ map f = fromList . List.map f . toList
11701211
{-# INLINABLE map #-}
11711212
#endif
11721213

1214+
mapNE :: Ord b => (a->b) -> NonEmptySet a -> NonEmptySet b
1215+
mapNE f = fromListNE . fmap f . toListNE
1216+
11731217
-- | /O(n)/. The
11741218
--
11751219
-- @'mapMonotonic' f s == 'map' f s@, but works only when @f@ is strictly increasing.
@@ -2314,6 +2358,14 @@ splitRoot orig =
23142358
NE (Bin' _ v l r) -> [l, singleton v, r]
23152359
{-# INLINE splitRoot #-}
23162360

2361+
splitRootNE :: NonEmptySet a -> NEL.NonEmpty (Set a)
2362+
splitRootNE (Bin' _ v l r) = l NEL.:| [singleton v, r]
2363+
2364+
splitNERootNE :: NonEmptySet a -> NEL.NonEmpty (NonEmptySet a)
2365+
splitNERootNE (Bin' _ v Tip Tip) = pure $ singletonNE v
2366+
splitNERootNE (Bin' _ v (NE l) Tip) = l NEL.:| [singletonNE v]
2367+
splitNERootNE (Bin' _ v Tip (NE r)) = singletonNE v NEL.:| [r]
2368+
splitNERootNE (Bin' _ v (NE l) (NE r)) = l NEL.:| [singletonNE v, r]
23172369

23182370
-- | Calculate the power set of a set: the set of all its subsets.
23192371
--
@@ -2333,6 +2385,24 @@ powerSet :: Set a -> Set (Set a)
23332385
powerSet xs0 = insertMin empty (foldr' step Tip xs0) where
23342386
step x pxs = insertMin (singleton x) (insertMin x `mapMonotonic` pxs) `glue` pxs
23352387

2388+
powerSetNE :: NonEmptySet a -> NonEmptySet (Set a)
2389+
powerSetNE xs = insertMinNE empty . NE . mapMonotonicNE NE $ nePowerSetNE xs
2390+
2391+
nePowerSetNE :: forall a . NonEmptySet a -> NonEmptySet (NonEmptySet a)
2392+
nePowerSetNE xs = foldr1By f (singletonNE.singletonNE) xs
2393+
where
2394+
f :: a -> NonEmptySet (NonEmptySet a) -> NonEmptySet (NonEmptySet a)
2395+
f v acc = insertMinNE (singletonNE v) (NE $ mapMonotonicNE (insertMinNE v . NE) acc) `glueNE` acc
2396+
2397+
foldr1By :: forall a b . (a -> b -> b) -> (a -> b) -> NonEmptySet a -> b
2398+
foldr1By f g = go
2399+
where
2400+
finish :: Set a -> b -> b
2401+
finish l acc = foldr f acc l
2402+
go :: NonEmptySet a -> b
2403+
go (Bin' _ v l (NE r)) = finish l (f v (go r))
2404+
go (Bin' _ v l Tip) = finish l (g v)
2405+
23362406
-- | /O(m*n)/ (conjectured). Calculate the Cartesian product of two sets.
23372407
--
23382408
-- @
@@ -2371,6 +2441,16 @@ cartesianProduct as (NE (Bin' 1 b _ _)) = mapMonotonic (flip (,) b) as
23712441
cartesianProduct as bs =
23722442
getMergeSet $ foldMap (\a -> MergeSet $ mapMonotonic ((,) a) bs) as
23732443

2444+
cartesianProductNE :: NonEmptySet a -> NonEmptySet b -> NonEmptySet (a, b)
2445+
cartesianProductNE as (Bin' 1 b _ _) = mapMonotonicNE (flip (,) b) as
2446+
cartesianProductNE as bs = goFoldMapNE as
2447+
where
2448+
f a = mapMonotonicNE ((,) a) bs
2449+
goFoldMapNE (Bin' 1 k _ _) = f k
2450+
goFoldMapNE (Bin' _ k l r) = goFoldMap l `mergeXNE` (f k `mergeNEX` goFoldMap r)
2451+
goFoldMap Tip = empty
2452+
goFoldMap (NE s) = NE $ goFoldMapNE s
2453+
23742454
-- A version of Set with peculiar Semigroup and Monoid instances.
23752455
-- The result of xs <> ys will only be a valid set if the greatest
23762456
-- element of xs is strictly less than the least element of ys.
@@ -2406,6 +2486,14 @@ instance Monoid (MergeSet a) where
24062486
disjointUnion :: Set a -> Set b -> Set (Either a b)
24072487
disjointUnion as bs = merge (mapMonotonic Left as) (mapMonotonic Right bs)
24082488

2489+
disjointUnionNE :: NonEmptySet a -> NonEmptySet b -> NonEmptySet (Either a b)
2490+
disjointUnionNE as bs = mergeNE (mapMonotonicNE Left as) (mapMonotonicNE Right bs)
2491+
2492+
disjointUnionNEX :: NonEmptySet a -> Set b -> NonEmptySet (Either a b)
2493+
disjointUnionNEX as bs = mergeNEX (mapMonotonicNE Left as) (mapMonotonic Right bs)
2494+
2495+
disjointUnionXNE :: Set a -> NonEmptySet b -> NonEmptySet (Either a b)
2496+
disjointUnionXNE as bs = mergeXNE (mapMonotonic Left as) (mapMonotonicNE Right bs)
24092497
{--------------------------------------------------------------------
24102498
Debugging
24112499
--------------------------------------------------------------------}

0 commit comments

Comments
 (0)