Skip to content

Add instances for HashMap/HashSet #149

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Breaking changes:

New features:
- Add `ifolded` and `imapped` (#146 by @twhitehead)
- Add `at`/`index` instances for `purescript-unordered-collections` (HashSet & HashMap)

Bugfixes:

Expand Down
1 change: 1 addition & 0 deletions packages.dhall
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
let upstream =
https://raw.githubusercontent.com/purescript/package-sets/psc-0.15.15-20240829/src/packages.dhall
sha256:5bab5469c75bd8c7bac517385e6dd66cca0b2651676b4a99b357753c80bbe673

in upstream
1 change: 1 addition & 0 deletions spago.dhall
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
, "safe-coerce"
, "transformers"
, "tuples"
, "unordered-collections"
]
, packages = ./packages.dhall
, sources = [ "src/**/*.purs", "test/**/*.purs" ]
Expand Down
17 changes: 17 additions & 0 deletions src/Data/Lens/At.purs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ module Data.Lens.At

import Prelude

import Data.Hashable (class Hashable)
import Data.Identity (Identity(..))
import Data.Lens (Lens', lens, set)
import Data.Lens.Index (class Index)
import Data.Map as M
import Data.HashMap as HM
import Data.Maybe (Maybe(..), maybe, maybe')
import Data.Newtype (unwrap)
import Data.Set as S
import Data.HashSet as HS
import Foreign.Object as FO

-- | `At` is a type class whose instances let you add
Expand Down Expand Up @@ -50,11 +53,25 @@ instance atSet :: Ord v => At (S.Set v) v Unit where
update Nothing = S.delete x
update (Just _) = S.insert x

instance atHashSet :: Hashable v => At (HS.HashSet v) v Unit where
at x = lens get (flip update)
where
get xs =
if HS.member x xs then Just unit
else Nothing
update Nothing = HS.delete x
update (Just _) = HS.insert x

instance atMap :: Ord k => At (M.Map k v) k v where
at k =
lens (M.lookup k) \m ->
maybe' (\_ -> M.delete k m) \v -> M.insert k v m

instance atHashMap :: Hashable k => At (HM.HashMap k v) k v where
at k =
lens (HM.lookup k) \m ->
maybe' (\_ -> HM.delete k m) \v -> HM.insert k v m

instance atForeignObject :: At (FO.Object v) String v where
at k =
lens (FO.lookup k) \m ->
Expand Down
21 changes: 21 additions & 0 deletions src/Data/Lens/Index.purs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module Data.Lens.Index

import Prelude

import Data.Hashable (class Hashable)
import Data.Array as A
import Data.Array.NonEmpty as NEA
import Data.Either (Either(..))
Expand All @@ -14,8 +15,10 @@ import Data.Lens.AffineTraversal (AffineTraversal', affineTraversal)
import Data.Lens.Iso.Newtype (_Newtype)
import Data.List as L
import Data.Map as M
import Data.HashMap as HM
import Data.Maybe (Maybe(..), fromMaybe, maybe)
import Data.Set as S
import Data.HashSet as HS
import Foreign.Object as FO

-- | `Index` is a type class whose instances are optics used when:
Expand Down Expand Up @@ -95,6 +98,15 @@ instance indexSet :: Ord a => Index (S.Set a) a Unit where
pre :: S.Set a -> Either (S.Set a) Unit
pre xs = if S.member x xs then Right unit else Left xs

instance indexHashSet :: Hashable a => Index (HS.HashSet a) a Unit where
ix x = affineTraversal set pre
where
set :: HS.HashSet a -> Unit -> HS.HashSet a
set xs _ = xs

pre :: HS.HashSet a -> Either (HS.HashSet a) Unit
pre xs = if HS.member x xs then Right unit else Left xs

instance indexMap :: Ord k => Index (M.Map k v) k v where
ix k = affineTraversal set pre
where
Expand All @@ -104,6 +116,15 @@ instance indexMap :: Ord k => Index (M.Map k v) k v where
pre :: M.Map k v -> Either (M.Map k v) v
pre s = maybe (Left s) Right $ M.lookup k s

instance indexHashMap :: Hashable k => Index (HM.HashMap k v) k v where
ix k = affineTraversal set pre
where
set :: HM.HashMap k v -> v -> HM.HashMap k v
set s b = HM.update (\_ -> Just b) k s

pre :: HM.HashMap k v -> Either (HM.HashMap k v) v
pre s = maybe (Left s) Right $ HM.lookup k s

instance indexForeignObject :: Index (FO.Object v) String v where
ix k = affineTraversal set pre
where
Expand Down