91 lines
3.3 KiB
Haskell
91 lines
3.3 KiB
Haskell
module Utils.Set
|
|
( setUnionAll
|
|
, setIntersectNotOne
|
|
, setIntersections
|
|
, setMapMaybe
|
|
, setSymmDiff
|
|
, setProduct
|
|
, setPartitionEithers
|
|
, setFromFunc
|
|
, mapIntersectNotOne
|
|
, getAllUserIdsSetList
|
|
) where
|
|
|
|
import qualified Data.Set as Set
|
|
import qualified Data.Map.Strict()
|
|
import qualified Data.Map as Map
|
|
import ClassyPrelude
|
|
import Data.Universe
|
|
import Control.Lens.Prism
|
|
import Control.Lens
|
|
|
|
-- | cardinal number of a Set
|
|
setUnionAll :: Ord a => [Set.Set a] -> Int
|
|
setUnionAll [] = 0
|
|
setUnionAll [x] = Set.size x
|
|
setUnionAll (x:y:z) = setUnionAll (xy:z) where xy = Set.union x y
|
|
|
|
-- | cardinal number of an intersection of a set and a list of sets
|
|
setIntersectNotOne :: Ord a => Set.Set a -> [Set.Set a] -> Int
|
|
setIntersectNotOne _ [] = 0
|
|
setIntersectNotOne k r = Set.size $ Set.intersection k others where others = setUnionOthers r
|
|
|
|
-- | Union of a list of sets
|
|
setUnionOthers :: Ord a => [Set.Set a] -> Set.Set a
|
|
setUnionOthers [] = Set.empty
|
|
setUnionOthers [x] = x
|
|
setUnionOthers (x:y:z) = setUnionOthers (xy:z) where xy = Set.union x y
|
|
|
|
----------------------------------
|
|
-- Functions fro Particiants.hs --
|
|
----------------------------------
|
|
|
|
-- | list of values of a Map with Sets as values
|
|
getAllUserIdsSetList :: Map.Map a (Set b) -> [Set b]
|
|
getAllUserIdsSetList m = loop (Map.toList m) [] where
|
|
loop [] uids = uids
|
|
loop ((_,v):xs) uids = loop xs $ uids ++ [v]
|
|
|
|
-- | value of a Map with given key
|
|
getUserIdsOfOneCourse :: (Ord a, Ord b) => Map.Map a (Set b) -> a -> Set b
|
|
getUserIdsOfOneCourse m cid
|
|
|m == Map.empty = Set.empty
|
|
|otherwise = m Map.! cid
|
|
|
|
-- | extracts from a map a list of values (sets) without one specific entry (a)
|
|
getAllUserIdsWithoutOne :: (Ord a, Ord b) => Map.Map a (Set b) -> a -> [Set b]
|
|
getAllUserIdsWithoutOne m cid
|
|
|m == Map.empty = []
|
|
|otherwise = getAllUserIdsSetList $ Map.delete cid m
|
|
|
|
-- | transforms values (sets) of a map to integers. The number gives information about how many entreis are not only in this one
|
|
mapIntersectNotOne :: (Ord a, Ord b) => Map.Map a (Set b) -> Map.Map a Int
|
|
mapIntersectNotOne m = loop (Map.toList m) Map.empty where
|
|
loop [] ino = ino
|
|
loop ((k,_):xs) ino = loop xs $ Map.insert k (setIntersectNotOne (getUserIdsOfOneCourse m k) (getAllUserIdsWithoutOne m k)) ino
|
|
|
|
-----------------------------
|
|
-- Functions from Utils.hs --
|
|
-----------------------------
|
|
|
|
-- | Intersection of multiple sets. Returns empty set for empty input list
|
|
setIntersections :: Ord a => [Set a] -> Set a
|
|
setIntersections [] = Set.empty
|
|
setIntersections (h:t) = foldl' Set.intersection h t
|
|
|
|
setMapMaybe :: Ord b => (a -> Maybe b) -> Set a -> Set b
|
|
setMapMaybe f = Set.fromList . mapMaybe f . Set.toList
|
|
|
|
-- | Symmetric difference of two sets.
|
|
setSymmDiff :: Ord a => Set a -> Set a -> Set a
|
|
setSymmDiff x y = (x `Set.difference` y) `Set.union` (y `Set.difference` x)
|
|
|
|
setProduct :: Set a -> Set b -> Set (a, b)
|
|
-- ^ Depends on the valid internal structure of the given sets
|
|
setProduct (Set.toAscList -> as) (Set.toAscList -> bs) = Set.fromDistinctAscList $ (,) <$> as <*> bs
|
|
|
|
setPartitionEithers :: (Ord a, Ord b) => Set (Either a b) -> (Set a, Set b)
|
|
setPartitionEithers = (,) <$> setMapMaybe (preview _Left) <*> setMapMaybe (preview _Right)
|
|
|
|
setFromFunc :: (Finite k, Ord k) => (k -> Bool) -> Set k
|
|
setFromFunc = Set.fromList . flip filter universeF |