1
1
{-# LANGUAGE CPP #-}
2
2
{-# LANGUAGE BangPatterns #-}
3
+ {-# LANGUAGE LambdaCase #-}
3
4
{-# LANGUAGE PatternGuards #-}
4
5
#if __GLASGOW_HASKELL__
5
6
{-# LANGUAGE DeriveDataTypeable, StandaloneDeriving #-}
@@ -294,6 +295,7 @@ type Size = Int
294
295
295
296
#if __GLASGOW_HASKELL__ >= 708
296
297
type role Set nominal
298
+ type role NonEmptySet nominal
297
299
#endif
298
300
299
301
instance Ord a => Monoid (Set a ) where
@@ -384,30 +386,52 @@ setDataType = mkDataType "Data.Set.Internal.Set" [fromListConstr]
384
386
--------------------------------------------------------------------}
385
387
-- | /O(1)/. Is this the empty set?
386
388
null :: Set a -> Bool
387
- null Tip = True
388
- null (NE (Bin {})) = False
389
+ null = \ case
390
+ Tip -> True
391
+ NE _ -> False
389
392
{-# INLINE null #-}
390
393
391
394
-- | /O(1)/. The number of elements in the set.
392
395
size :: Set a -> Int
393
- size Tip = 0
394
- size (NE (Bin sz _ _ _)) = sz
396
+ size = \ case
397
+ Tip -> 0
398
+ NE ne -> sizeNE ne
395
399
{-# INLINE size #-}
396
400
401
+ sizeNE :: NonEmptySet a -> Int
402
+ sizeNE (Bin sz _ _ _) = sz
403
+ {-# INLINE sizeNE #-}
404
+
397
405
-- | /O(log n)/. Is the element in the set?
398
406
member :: Ord a => a -> Set a -> Bool
399
- member = go
407
+ member = fst . makeMember
408
+
409
+ memberNE :: Ord a => a -> NonEmptySet a -> Bool
410
+ memberNE = snd . makeMember
411
+
412
+ makeMember
413
+ :: Ord a
414
+ => a
415
+ -> ( Set a -> Bool
416
+ , NonEmptySet a -> Bool
417
+ )
418
+ makeMember ! x = (go, go')
400
419
where
401
- go ! _ Tip = False
402
- go x (NE (Bin _ y l r)) = case compare x y of
403
- LT -> go x l
404
- GT -> go x r
420
+ go Tip = False
421
+ go (NE ne) = go' ne
422
+
423
+ go' (Bin _ y l r) = case compare x y of
424
+ LT -> go l
425
+ GT -> go r
405
426
EQ -> True
406
427
#if __GLASGOW_HASKELL__
407
428
{-# INLINABLE member #-}
429
+ {-# INLINABLE memberNE #-}
408
430
#else
409
431
{-# INLINE member #-}
432
+ {-# INLINE memberNE #-}
410
433
#endif
434
+ {-# INLINE makeMember #-}
411
435
412
436
-- | /O(log n)/. Is the element not in the set?
413
437
notMember :: Ord a => a -> Set a -> Bool
@@ -418,51 +442,95 @@ notMember a t = not $ member a t
418
442
{-# INLINE notMember #-}
419
443
#endif
420
444
445
+ notMemberNE :: Ord a => a -> NonEmptySet a -> Bool
446
+ notMemberNE a t = not $ memberNE a t
447
+ #if __GLASGOW_HASKELL__
448
+ {-# INLINABLE notMemberNE #-}
449
+ #else
450
+ {-# INLINE notMemberNE #-}
451
+ #endif
452
+
421
453
-- | /O(log n)/. Find largest element smaller than the given one.
422
454
--
423
455
-- > lookupLT 3 (fromList [3, 5]) == Nothing
424
456
-- > lookupLT 5 (fromList [3, 5]) == Just 3
425
457
lookupLT :: Ord a => a -> Set a -> Maybe a
426
- lookupLT = goNothing
458
+ lookupLT = fst . makeLookupLT
459
+
460
+ lookupLTNE :: Ord a => a -> NonEmptySet a -> Maybe a
461
+ lookupLTNE = snd . makeLookupLT
462
+
463
+ makeLookupLT
464
+ :: Ord a
465
+ => a
466
+ -> ( Set a -> Maybe a
467
+ , NonEmptySet a -> Maybe a
468
+ )
469
+ makeLookupLT ! x = (goNothing, goNothing')
427
470
where
428
- goNothing ! _ Tip = Nothing
429
- goNothing x (NE (Bin _ y l r))
430
- | x <= y = goNothing x l
431
- | otherwise = goJust x y r
471
+ goNothing Tip = Nothing
472
+ goNothing (NE ne) = goNothing' ne
432
473
433
- goJust ! _ best Tip = Just best
434
- goJust x best (NE (Bin _ y l r))
435
- | x <= y = goJust x best l
436
- | otherwise = goJust x y r
474
+ goNothing' (Bin _ y l r)
475
+ | x <= y = goNothing l
476
+ | otherwise = goJust y r
477
+
478
+ goJust best Tip = Just best
479
+ goJust best (NE ne) = goJust' best ne
480
+
481
+ goJust' best (Bin _ y l r)
482
+ | x <= y = goJust best l
483
+ | otherwise = goJust y r
437
484
438
485
#if __GLASGOW_HASKELL__
439
486
{-# INLINABLE lookupLT #-}
487
+ {-# INLINABLE lookupLTNE #-}
440
488
#else
441
489
{-# INLINE lookupLT #-}
490
+ {-# INLINE lookupLTNE #-}
442
491
#endif
492
+ {-# INLINE makeLookupLT #-}
443
493
444
494
-- | /O(log n)/. Find smallest element greater than the given one.
445
495
--
446
496
-- > lookupGT 4 (fromList [3, 5]) == Just 5
447
497
-- > lookupGT 5 (fromList [3, 5]) == Nothing
448
498
lookupGT :: Ord a => a -> Set a -> Maybe a
449
- lookupGT = goNothing
499
+ lookupGT = fst . makeLookupGT
500
+
501
+ lookupGTNE :: Ord a => a -> NonEmptySet a -> Maybe a
502
+ lookupGTNE = snd . makeLookupGT
503
+
504
+ makeLookupGT
505
+ :: Ord a
506
+ => a
507
+ -> ( Set a -> Maybe a
508
+ , NonEmptySet a -> Maybe a
509
+ )
510
+ makeLookupGT ! x = (goNothing, goNothing')
450
511
where
451
- goNothing ! _ Tip = Nothing
452
- goNothing x (NE (Bin _ y l r))
453
- | x < y = goJust x y l
454
- | otherwise = goNothing x r
512
+ goNothing Tip = Nothing
513
+ goNothing (NE ne) = goNothing' ne
455
514
456
- goJust ! _ best Tip = Just best
457
- goJust x best (NE (Bin _ y l r))
458
- | x < y = goJust x y l
459
- | otherwise = goJust x best r
515
+ goNothing' (Bin _ y l r)
516
+ | x < y = goJust y l
517
+ | otherwise = goNothing r
518
+
519
+ goJust best Tip = Just best
520
+ goJust best (NE ne) = goJust' best ne
521
+
522
+ goJust' best (Bin _ y l r)
523
+ | x < y = goJust y l
524
+ | otherwise = goJust best r
460
525
461
526
#if __GLASGOW_HASKELL__
462
527
{-# INLINABLE lookupGT #-}
528
+ {-# INLINABLE lookupGTNE #-}
463
529
#else
464
530
{-# INLINE lookupGT #-}
531
+ {-# INLINE lookupGTNE #-}
465
532
#endif
533
+ {-# INLINE makeLookupGT #-}
466
534
467
535
-- | /O(log n)/. Find largest element smaller or equal to the given one.
468
536
--
@@ -526,9 +594,13 @@ empty = Tip
526
594
527
595
-- | /O(1)/. Create a singleton set.
528
596
singleton :: a -> Set a
529
- singleton x = NE $ Bin 1 x Tip Tip
597
+ singleton = NE . singletonNE
530
598
{-# INLINE singleton #-}
531
599
600
+ singletonNE :: a -> NonEmptySet a
601
+ singletonNE x = Bin 1 x Tip Tip
602
+ {-# INLINE singletonNE #-}
603
+
532
604
{- -------------------------------------------------------------------
533
605
Insertion, Deletion
534
606
--------------------------------------------------------------------}
0 commit comments