-- | A set of unique values. The values can be any comparable type. This -- includes @Int@, @Float@, @Time@, @Char@, @String@, and tuples or lists -- of comparable types. -- -- Insert, remove, and query operations all take /O(log n)/ time. module Set ( -- * Sets Set, -- * Build empty, singleton, insert, remove, -- * Query isEmpty, member, size, -- * Combine union, intersect, diff, -- * Lists toList, fromList, -- * Transform map, foldl, foldr, filter, partition, ) where import Basics (Bool, Int, Ord, (>>)) import qualified Data.Set import List (List) import qualified Prelude -- | Represents a set of unique values. So @(Set Int)@ is a set of integers and -- @(Set String)@ is a set of strings. type Set t = Data.Set.Set t -- | Create an empty set. empty :: Set a empty = Data.Set.empty -- | Create a set with one value. singleton :: comparable -> Set comparable singleton = Data.Set.singleton -- | Insert a value into a set. insert :: Ord comparable => comparable -> Set comparable -> Set comparable insert = Data.Set.insert -- | Remove a value from a set. If the value is not found, no changes are made. remove :: Ord comparable => comparable -> Set comparable -> Set comparable remove = Data.Set.delete -- | Determine if a set is empty. isEmpty :: Set a -> Bool isEmpty = Data.Set.null -- | Determine if a value is in a set. member :: Ord comparable => comparable -> Set comparable -> Bool member = Data.Set.member -- | Determine the number of elements in a set. size :: Set a -> Int size = Data.Set.size >> Prelude.fromIntegral -- | Get the union of two sets, preferring the first set when equal elements are -- encountered. -- -- In Elm it's not possible to have two comparable elements that are not equal, but -- it is possible in Haskell. union :: Ord comparable => Set comparable -> Set comparable -> Set comparable union = Data.Set.union -- | Get the intersection of two sets, preferring the first set when equal elements -- are encountered. -- -- In Elm it's not possible to have two comparable elements that are not equal, but -- it is possible in Haskell. intersect :: Ord comparable => Set comparable -> Set comparable -> Set comparable intersect = Data.Set.intersection -- | Get the difference between the first set and the second. Keeps values -- that do not appear in the second set. diff :: Ord comparable => Set comparable -> Set comparable -> Set comparable diff = Data.Set.difference -- | Convert a set into a list, sorted from lowest to highest. toList :: Set a -> List a toList = Data.Set.toAscList -- | Convert a list into a set, removing any duplicates. fromList :: Ord comparable => List comparable -> Set comparable fromList = Data.Set.fromList -- | Fold over the values in a set, in order from lowest to highest. foldl :: (a -> b -> b) -> b -> Set a -> b foldl func = Data.Set.foldl' (\a b -> func b a) -- | Fold over the values in a set, in order from highest to lowest. foldr :: (a -> b -> b) -> b -> Set a -> b foldr = Data.Set.foldr' -- | Map a function onto a set, creating a new set with no duplicates. map :: Ord comparable2 => (comparable -> comparable2) -> Set comparable -> Set comparable2 map = Data.Set.map -- | Only keep elements that pass the given test. -- -- > import Set exposing (Set) -- > -- > numbers : Set Int -- > numbers = -- > Set.fromList [-2,-1,0,1,2] -- > -- > positives : Set Int -- > positives = -- > Set.filter (\x -> x > 0) numbers -- > -- > -- positives == Set.fromList [1,2] filter :: (comparable -> Bool) -> Set comparable -> Set comparable filter = Data.Set.filter -- | Create two new sets. The first contains all the elements that passed the -- given test, and the second contains all the elements that did not. partition :: (comparable -> Bool) -> Set comparable -> (Set comparable, Set comparable) partition = Data.Set.partition