Skip to content

Commit

Permalink
Add unions and toUnfoldable to HashSet API (#24)
Browse files Browse the repository at this point in the history
Closes #23. Thanks @JordanMartinez!
  • Loading branch information
fehrenbach authored Nov 15, 2020
1 parent e916283 commit c2008e1
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 3 deletions.
4 changes: 3 additions & 1 deletion bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@
"output"
],
"dependencies": {
"purescript-arrays": "^5.0.0",
"purescript-enums": "^4.0.1",
"purescript-functions": "^4.0.0",
"purescript-integers": "^4.0.0",
"purescript-lists": "^5.4.1",
"purescript-prelude": "^4.1.1",
"purescript-record": "^2.0.1",
"purescript-tuples": "^5.1.0",
"purescript-typelevel-prelude": "^5.0.0"
"purescript-typelevel-prelude": "^5.0.0",
"purescript-unfoldable": "^4.0.0"
},
"devDependencies": {
"purescript-foreign-object": "^2.0.2",
Expand Down
19 changes: 17 additions & 2 deletions src/Data/HashSet.purs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ module Data.HashSet (
mapMaybe,

union,
unions,
intersection,
difference,

Expand All @@ -26,16 +27,19 @@ module Data.HashSet (

fromArray,
fromFoldable,
toArray
toArray,
toUnfoldable
) where

import Prelude hiding (map)

import Data.Foldable (class Foldable, foldr)
import Data.Array as Array
import Data.Foldable (class Foldable, foldr, fold)
import Data.FoldableWithIndex (foldMapWithIndex, foldlWithIndex, foldrWithIndex)
import Data.HashMap as M
import Data.Hashable (class Hashable)
import Data.Maybe (Maybe(..))
import Data.Unfoldable (class Unfoldable)

-- | A `HashSet a` is a set with elements of type `a`.
-- |
Expand Down Expand Up @@ -120,6 +124,10 @@ mapMaybe f =
union :: forall a. Hashable a => HashSet a -> HashSet a -> HashSet a
union (HashSet l) (HashSet r) = HashSet (M.unionWith const l r)

-- | Union a collection of sets.
unions :: forall f a. Foldable f => Hashable a => f (HashSet a) -> HashSet a
unions = fold

-- | Intersect two sets.
intersection :: forall a. Hashable a => HashSet a -> HashSet a -> HashSet a
intersection (HashSet l) (HashSet r) = HashSet (M.intersectionWith const l r)
Expand Down Expand Up @@ -149,3 +157,10 @@ isEmpty (HashSet m) = M.isEmpty m
-- | `fromFoldable`.
fromArray :: forall a. Hashable a => Array a -> HashSet a
fromArray = HashSet <<< M.fromArrayBy identity (const unit)

-- | Turn a set into an unfoldable functor.
-- |
-- | You probably want to use `toArray` instead, especially if you
-- | want to get an array out.
toUnfoldable :: forall f a. Unfoldable f => HashSet a -> f a
toUnfoldable = Array.toUnfoldable <<< toArray
5 changes: 5 additions & 0 deletions test/Main.purs
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,11 @@ main = do
quickCheck' 10000 \(a :: Array CollidingInt) ->
HS.empty `HS.union` HS.fromFoldable a === HS.fromFoldable a

log "unions = foldl union empty"
quickCheck \(as :: Array (Array CollidingInt)) ->
let hss = map HS.fromFoldable as
in HS.unions hss === foldl HS.union HS.empty hss

log "intersection with empty"
quickCheck' 10000 \(a :: Array CollidingInt) ->
HS.fromFoldable a `HS.intersection` HS.empty === HS.empty
Expand Down

0 comments on commit c2008e1

Please sign in to comment.