fresnel-0.0.0.0: src/Fresnel/At.hs
{-# LANGUAGE RankNTypes #-}
module Fresnel.At
( -- * Updateable collections
At(..)
, Index
, IxValue
-- * Construction
, atSet
, atMap
, ixAt
-- * Elimination
, sans
) where
import Control.Monad (guard)
import qualified Data.HashMap.Internal.Strict as HashMap
import qualified Data.HashSet as HashSet
import Data.Hashable
import qualified Data.IntMap as IntMap
import qualified Data.IntSet as IntSet
import qualified Data.Map as Map
import qualified Data.Set as Set
import Fresnel.Ixed
import Fresnel.Lens (Lens', lens)
import Fresnel.Maybe (_Just)
import Fresnel.Optional (Optional')
import Fresnel.Setter
-- Updateable collections
class Ixed c => At c where
at :: Index c -> Lens' c (Maybe (IxValue c))
instance At IntSet.IntSet where
at = atSet IntSet.member IntSet.insert IntSet.delete
instance At (IntMap.IntMap v) where
at = atMap IntMap.lookup IntMap.insert IntMap.delete
instance Ord k => At (Set.Set k) where
at = atSet Set.member Set.insert Set.delete
instance Ord k => At (Map.Map k v) where
at = atMap Map.lookup Map.insert Map.delete
instance (Eq k, Hashable k) => At (HashSet.HashSet k) where
at = atSet HashSet.member HashSet.insert HashSet.delete
instance (Eq k, Hashable k) => At (HashMap.HashMap k v) where
at = atMap HashMap.lookup HashMap.insert HashMap.delete
instance At (Maybe a) where
at _ = lens id (const id)
-- Construction
atSet :: (Index c -> c -> Bool) -> (Index c -> c -> c) -> (Index c -> c -> c) -> Index c -> Lens' c (Maybe ())
atSet member insert delete k = lens (guard . member k) (\ s -> maybe (delete k s) (const (insert k s)))
atMap :: (Index c -> c -> Maybe (IxValue c)) -> (Index c -> IxValue c -> c -> c) -> (Index c -> c -> c) -> Index c -> Lens' c (Maybe (IxValue c))
atMap lookup insert delete k = lens (lookup k) (\ m -> maybe (delete k m) (flip (insert k) m))
ixAt :: At a => Index a -> Optional' a (IxValue a)
ixAt i = at i . _Just
-- Elimination
sans :: At c => Index c -> c -> c
sans k = at k .~ Nothing