New paste Repaste Download
{-# Language RankNTypes #-}
{-# Language StandaloneDeriving #-}
module RevdepScanner.Types.HashSet.NonEmpty
    ( NonEmptyHashSet
    , fromHashSet
    , toHashSet
    , singleton
    , insert
    , union
    , fromList
    ) where
import Data.Foldable (foldl')
import Data.Hashable (Hashable, Hashed, hashed, unhashed)
import           Data.HashSet (HashSet)
import qualified Data.HashSet as S
-- | A 'HashSet', but it must contain at least one element
data NonEmptyHashSet a
    = Hashable a => NEHashSet (Hashed a) (HashSet a)
deriving instance Show a => Show (NonEmptyHashSet a)
deriving instance Eq (NonEmptyHashSet a)
deriving instance Ord a => Ord (NonEmptyHashSet a)
instance Foldable NonEmptyHashSet where
    foldMap f = foldMap f . toHashSet
instance Semigroup (NonEmptyHashSet a) where
    (<>) = union
-- | @O(n)@
fromHashSet :: Hashable a => HashSet a -> Maybe (NonEmptyHashSet a)
fromHashSet = fromList . S.toList
-- | @O(log n)@
toHashSet :: NonEmptyHashSet a -> HashSet a
toHashSet (NEHashSet x s) = S.insert (unhashed x) s
-- | @O(1)@
singleton :: Hashable a => a -> NonEmptyHashSet a
singleton x = NEHashSet (hashed x) S.empty
-- | @O(log n)@
insert :: Hashable a => a -> NonEmptyHashSet a -> NonEmptyHashSet a
insert x nes@(NEHashSet y s)
    | hashed x == y = nes
    | otherwise = NEHashSet y (S.insert x s)
-- | @O(n+m)@
union :: NonEmptyHashSet a -> NonEmptyHashSet a -> NonEmptyHashSet a
union nes1@(NEHashSet x1 s1) (NEHashSet x2 s2)
    | x1 == x2 = NEHashSet x1 (s1 <> s2)
    | otherwise = NEHashSet x1 (toHashSet nes1 <> s2)
-- | @O(n)@
fromList :: Hashable a => [a] -> Maybe (NonEmptyHashSet a)
fromList [] = Nothing
fromList (x:xs) = Just $ foldl' (flip insert) (singleton x) xs
Filename: stdin. Size: 2kb. View raw, , hex, or download this file.

This paste expires on 2025-11-03 03:58:46.112991. Pasted through v1-api.