packages feed

strict-containers-lens (empty) → 0.1

raw patch · 9 files changed

+539/−0 lines, 9 filesdep +basedep +hashabledep +lens

Dependencies added: base, hashable, lens, strict-containers

Files

+ CHANGELOG.md view
@@ -0,0 +1,7 @@+# Revision history for strict-containers-lens++## 0.1 -- 2021-04-20++- Initial release, defining lens instances for `Data.Strict.HashMap`,+  `Data.Strict.IntMap`, `Data.Strict.Map`, `Data.Strict.Sequence`, and+  `Data.Strict.Vector`.
+ LICENSE view
@@ -0,0 +1,24 @@+Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:++1. Redistributions of source code must retain the above copyright+   notice, this list of conditions and the following disclaimer.+2. Redistributions in binary form must reproduce the above copyright+   notice, this list of conditions and the following disclaimer in the+   documentation and/or other materials provided with the distribution.+3. Neither the name of the author nor the names of his contributors+   may be used to endorse or promote products derived from this software+   without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+SUCH DAMAGE.
+ src/Data/Strict/Containers/Lens.hs view
@@ -0,0 +1,10 @@+{- | Convenience module for importing all strict-containers lens instances. -}+module Data.Strict.Containers.Lens+  (+  ) where++import           Data.Strict.HashMap.Lens ()+import           Data.Strict.IntMap.Lens ()+import           Data.Strict.Map.Lens ()+import           Data.Strict.Sequence.Lens ()+import           Data.Strict.Vector.Lens ()
+ src/Data/Strict/HashMap/Lens.hs view
@@ -0,0 +1,63 @@+{-# LANGUAGE CPP                   #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RankNTypes            #-}+{-# LANGUAGE TypeFamilies          #-}+{-# LANGUAGE UndecidableInstances  #-}++{-# OPTIONS_GHC -fno-warn-orphans #-}+module Data.Strict.HashMap.Lens+  (+  ) where++import           Control.Lens+import           Data.Hashable (Hashable)++import qualified Data.Strict.HashMap as HM++import           Data.Strict.HashMap (HashMap)+++#if !MIN_VERSION_lens(5,0,0)+instance FunctorWithIndex k (HashMap k) where+  imap = HM.mapWithKey+  {-# INLINE imap #-}++instance FoldableWithIndex k (HashMap k) where+  ifoldr  = HM.foldrWithKey+  {-# INLINE ifoldr #-}+  ifoldl' = HM.foldlWithKey' . flip+  {-# INLINE ifoldl' #-}++instance TraversableWithIndex k (HashMap k) where+  itraverse = HM.traverseWithKey+  {-# INLINE itraverse #-}+#endif++type instance Index (HashMap k v) = k+type instance IxValue (HashMap k v) = v++instance (Eq k, Hashable k) => Ixed (HashMap k a) where+  ix k f m = case HM.lookup k m of+     Just v  -> f v <&> \v' -> HM.insert k v' m+     Nothing -> pure m+  {-# INLINE ix #-}++instance (Eq k, Hashable k) => At (HashMap k v) where+  at k f = HM.alterF f k+  {-# INLINE at #-}++instance AsEmpty (HashMap k a) where+  _Empty = nearly HM.empty HM.null+  {-# INLINE _Empty #-}++instance (c ~ d) => Each (HashMap c a) (HashMap d b) a b where+  each = traversed+  {-# INLINE each #-}++instance (t ~ HashMap k' a', Hashable k, Eq k) => Rewrapped (HashMap k a) t+instance (Hashable k, Eq k) => Wrapped (HashMap k a) where+  type Unwrapped (HashMap k a) = [(k, a)]+  _Wrapped' = iso HM.toList HM.fromList+  {-# INLINE _Wrapped' #-}
+ src/Data/Strict/IntMap/Lens.hs view
@@ -0,0 +1,75 @@+{-# LANGUAGE CPP                   #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RankNTypes            #-}+{-# LANGUAGE TypeFamilies          #-}+{-# LANGUAGE UndecidableInstances  #-}++{-# OPTIONS_GHC -fno-warn-orphans #-}+module Data.Strict.IntMap.Lens+  (+  ) where++import           Control.Lens++import qualified Data.Strict.IntMap as IM++import           Data.Strict.IntMap (IntMap)+++#if !MIN_VERSION_lens(5,0,0)+instance FunctorWithIndex Int IntMap where+  imap = IM.mapWithKey+  {-# INLINE imap #-}++instance FoldableWithIndex Int IntMap where+  ifoldMap = IM.foldMapWithKey+  {-# INLINE ifoldMap #-}+  ifoldr   = IM.foldrWithKey+  {-# INLINE ifoldr #-}+  ifoldl'  = IM.foldlWithKey' . flip+  {-# INLINE ifoldl' #-}++instance TraversableWithIndex Int IntMap where+  itraverse = IM.traverseWithKey+  {-# INLINE itraverse #-}+#endif++type instance Index (IntMap a) = Int+type instance IxValue (IntMap a) = a+instance Ixed (IntMap a) where+  ix k f m = case IM.lookup k m of+     Just v -> f v <&> \v' -> IM.insert k v' m+     Nothing -> pure m+  {-# INLINE ix #-}++instance At (IntMap a) where+  at k f = IM.alterF f k+  {-# INLINE at #-}++instance AsEmpty (IntMap a) where+  _Empty = nearly IM.empty IM.null+  {-# INLINE _Empty #-}++instance Each (IntMap a) (IntMap b) a b where+  each = traversed+  {-# INLINE each #-}++instance (t ~ IntMap a') => Rewrapped (IntMap a) t+instance Wrapped (IntMap a) where+  type Unwrapped (IntMap a) = [(Int, a)]+  _Wrapped' = iso IM.toAscList IM.fromList+  {-# INLINE _Wrapped' #-}++instance TraverseMin Int IntMap where+  traverseMin f m = case IM.minViewWithKey m of+    Just ((k,a), _) -> indexed f k a <&> \v -> IM.updateMin (const (Just v)) m+    Nothing     -> pure m+  {-# INLINE traverseMin #-}++instance TraverseMax Int IntMap where+  traverseMax f m = case IM.maxViewWithKey m of+    Just ((k,a), _) -> indexed f k a <&> \v -> IM.updateMax (const (Just v)) m+    Nothing     -> pure m+  {-# INLINE traverseMax #-}
+ src/Data/Strict/Map/Lens.hs view
@@ -0,0 +1,80 @@+{-# LANGUAGE CPP                   #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RankNTypes            #-}+{-# LANGUAGE TypeFamilies          #-}+{-# LANGUAGE UndecidableInstances  #-}++{-# OPTIONS_GHC -fno-warn-orphans #-}+module Data.Strict.Map.Lens+  ( toMapOf+  ) where++import           Control.Lens++import qualified Data.Strict.Map as M++import           Data.Strict.Map (Map)+++#if !MIN_VERSION_lens(5,0,0)+instance FunctorWithIndex k (Map k) where+  imap = M.mapWithKey+  {-# INLINE imap #-}++instance FoldableWithIndex k (Map k) where+  ifoldMap = M.foldMapWithKey+  {-# INLINE ifoldMap #-}+  ifoldr   = M.foldrWithKey+  {-# INLINE ifoldr #-}+  ifoldl'  = M.foldlWithKey' . flip+  {-# INLINE ifoldl' #-}++instance TraversableWithIndex k (Map k) where+  itraverse = M.traverseWithKey+  {-# INLINE itraverse #-}+#endif++type instance Index (Map k v) = k+type instance IxValue (Map k v) = v++instance Ord k => Ixed (Map k a) where+  ix k f m = case M.lookup k m of+     Just v  -> f v <&> \v' -> M.insert k v' m+     Nothing -> pure m+  {-# INLINE ix #-}++instance Ord k => At (Map k v) where+  at k f = M.alterF f k+  {-# INLINE at #-}++instance AsEmpty (Map k a) where+  _Empty = nearly M.empty M.null+  {-# INLINE _Empty #-}++instance (c ~ d) => Each (Map c a) (Map d b) a b where+  each = traversed+  {-# INLINE each #-}++instance (t ~ Map k' a', Ord k) => Rewrapped (Map k a) t+instance Ord k => Wrapped (Map k a) where+  type Unwrapped (Map k a) = [(k, a)]+  _Wrapped' = iso M.toAscList M.fromList+  {-# INLINE _Wrapped' #-}++instance Ord k => TraverseMin k (Map k) where+  traverseMin f m = case M.minViewWithKey m of+    Just ((k, a), _) -> indexed f k a <&> \v -> M.updateMin (const (Just v)) m+    Nothing          -> pure m+  {-# INLINE traverseMin #-}++instance Ord k => TraverseMax k (Map k) where+  traverseMax f m = case M.maxViewWithKey m of+    Just ((k, a), _) -> indexed f k a <&> \v -> M.updateMax (const (Just v)) m+    Nothing          -> pure m+  {-# INLINE traverseMax #-}++-- | Analogous to 'Data.Map.Lens.toMapOf'.+toMapOf :: IndexedGetting i (Map i a) s a -> s -> Map i a+toMapOf l = iviews l M.singleton
+ src/Data/Strict/Sequence/Lens.hs view
@@ -0,0 +1,120 @@+{-# LANGUAGE CPP                   #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RankNTypes            #-}+{-# LANGUAGE TypeFamilies          #-}+{-# LANGUAGE UndecidableInstances  #-}++{-# OPTIONS_GHC -fno-warn-orphans #-}+module Data.Strict.Sequence.Lens+  ( viewL+  , viewR+  , slicedTo+  , slicedFrom+  , sliced+  , seqOf+  ) where++import           Control.Lens++import qualified Data.Foldable as Foldable+import qualified Data.Strict.Sequence as Seq++import           Data.Strict.Sequence (Seq, ViewL(EmptyL), ViewR(EmptyR), (><), viewl, viewr)+++#if !MIN_VERSION_lens(5,0,0)+instance FunctorWithIndex Int Seq where+  imap = Seq.mapWithIndex+  {-# INLINE imap #-}++instance FoldableWithIndex Int Seq where+  ifoldMap = Seq.foldMapWithIndex+  {-# INLINE ifoldMap #-}+  ifoldr = Seq.foldrWithIndex+  {-# INLINE ifoldr #-}+  ifoldl f = Seq.foldlWithIndex (flip f)+  {-# INLINE ifoldl #-}++instance TraversableWithIndex Int Seq where+  itraverse = Seq.traverseWithIndex+  {-# INLINE itraverse #-}+#endif++type instance Index (Seq a) = Int+type instance IxValue (Seq a) = a+instance Ixed (Seq a) where+  -- This is slightly different from lens' definition to make our ixTest work.+  -- It is analogous to how Map.ix is defined.+  ix i f m = case Seq.lookup i m of+    Nothing -> pure m+    Just v -> f v <&> \a -> Seq.update i a m+  {-# INLINE ix #-}++instance AsEmpty (Seq a) where+  _Empty = nearly Seq.empty Seq.null+  {-# INLINE _Empty #-}++instance Each (Seq a) (Seq b) a b where+  each = traversed+  {-# INLINE each #-}++instance (t ~ Seq a') => Rewrapped (Seq a) t+instance Wrapped (Seq a) where+  type Unwrapped (Seq a) = [a]+  _Wrapped' = iso Foldable.toList Seq.fromList+  {-# INLINE _Wrapped' #-}++instance Cons (Seq a) (Seq b) a b where+  _Cons = prism (uncurry (Seq.<|)) $ \aas -> case viewl aas of+    a Seq.:< as -> Right (a, as)+    EmptyL  -> Left mempty+  {-# INLINE _Cons #-}++instance Snoc (Seq a) (Seq b) a b where+  _Snoc = prism (uncurry (Seq.|>)) $ \aas -> case viewr aas of+    as Seq.:> a -> Right (as, a)+    EmptyR  -> Left mempty+  {-# INLINE _Snoc #-}++instance Reversing (Seq a) where+  reversing = Seq.reverse++-- | Analogous to 'Data.Sequence.Lens.viewL'.+viewL :: Iso (Seq a) (Seq b) (ViewL a) (ViewL b)+viewL = iso viewl $ \ xs -> case xs of+  EmptyL ->  mempty+  a Seq.:< as -> a Seq.<| as+{-# INLINE viewL #-}++-- | Analogous to 'Data.Sequence.Lens.viewR'.+viewR :: Iso (Seq a) (Seq b) (ViewR a) (ViewR b)+viewR = iso viewr $ \xs -> case xs of+  EmptyR  -> mempty+  as Seq.:> a -> as Seq.|> a+{-# INLINE viewR #-}++-- | Analogous to 'Data.Sequence.Lens.slicedTo'.+slicedTo :: Int -> IndexedTraversal' Int (Seq a) a+slicedTo n f m = case Seq.splitAt n m of+  (l,r) -> (>< r) <$> itraverse (indexed f) l+{-# INLINE slicedTo #-}++-- | Analogous to 'Data.Sequence.Lens.slicedFrom'.+slicedFrom :: Int -> IndexedTraversal' Int (Seq a) a+slicedFrom n f m = case Seq.splitAt n m of+  (l,r) -> (l ><) <$> itraverse (indexed f . (+n)) r+{-# INLINE slicedFrom #-}++-- | Analogous to 'Data.Sequence.Lens.sliced'.+sliced :: Int -> Int -> IndexedTraversal' Int (Seq a) a+sliced i j f s = case Seq.splitAt i s of+  (l,mr) -> case Seq.splitAt (j-i) mr of+     (m, r) -> itraverse (indexed f . (+i)) m <&> \n -> l >< n >< r+{-# INLINE sliced #-}++-- | Analogous to 'Data.Sequence.Lens.seqOf'.+seqOf :: Getting (Seq a) s a -> s -> Seq a+seqOf l = views l Seq.singleton+{-# INLINE seqOf #-}
+ src/Data/Strict/Vector/Lens.hs view
@@ -0,0 +1,119 @@+{-# LANGUAGE BangPatterns          #-}+{-# LANGUAGE CPP                   #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RankNTypes            #-}+{-# LANGUAGE TypeFamilies          #-}+{-# LANGUAGE UndecidableInstances  #-}++{-# OPTIONS_GHC -fno-warn-orphans #-}+module Data.Strict.Vector.Lens+  ( toVectorOf+  , vector+  , forced+  , sliced+  , ordinals+  ) where++import           Control.Lens+import           Control.Lens.Internal.List (ordinalNub)+import           Data.Vector.Generic.Lens (vectorTraverse)+import           Data.Monoid (Endo)++import qualified Data.Strict.Vector as V++import           Data.Strict.Vector (Vector)+++#if !MIN_VERSION_lens(5,0,0)+instance FunctorWithIndex Int Vector where+  imap = V.imap+  {-# INLINE imap #-}++instance FoldableWithIndex Int Vector where+  ifoldr = V.ifoldr+  {-# INLINE ifoldr #-}+  ifoldl = V.ifoldl . flip+  {-# INLINE ifoldl #-}+  ifoldr' = V.ifoldr'+  {-# INLINE ifoldr' #-}+  ifoldl' = V.ifoldl' . flip+  {-# INLINE ifoldl' #-}++instance TraversableWithIndex Int Vector where+  itraverse f v =+    let !n = V.length v in V.fromListN n <$> itraverse f (V.toList v)+  {-# INLINE itraverse #-}+#endif++type instance Index (Vector a) = Int+type instance IxValue (Vector a) = a+instance Ixed (Vector a) where+  -- This is slightly different from lens' definition to make our ixTest work.+  -- Unlike Sequence, since the element is stored inside a primitive array the+  -- only way to get it is via a primop, so we have to force-apply ($!) the+  -- extraction. Pattern matching on a case-expr (e.g. the result of V.!?) is+  -- ineffective because that still has to call the primop, so we would still+  -- have a thunk after pattern matching.+  ix i f v+    | 0 <= i && i < V.length v = (f $! v V.! i) <&> \a -> v V.// [(i, a)]+    | otherwise                     = pure v+  {-# INLINE ix #-}++instance AsEmpty (Vector a) where+  _Empty = nearly V.empty V.null+  {-# INLINE _Empty #-}++instance Each (Vector a) (Vector b) a b where+  each = vectorTraverse+  {-# INLINE each #-}++instance (t ~ Vector a') => Rewrapped (Vector a) t+instance Wrapped (Vector a) where+  type Unwrapped (Vector a) = [a]+  _Wrapped' = iso V.toList V.fromList+  {-# INLINE _Wrapped' #-}++instance Cons (Vector a) (Vector b) a b where+  _Cons = prism (uncurry V.cons) $ \v ->+    if V.null v+    then Left V.empty+    else Right (V.unsafeHead v, V.unsafeTail v)+  {-# INLINE _Cons #-}++instance Snoc (Vector a) (Vector b) a b where+  _Snoc = prism (uncurry V.snoc) $ \v -> if V.null v+    then Left V.empty+    else Right (V.unsafeInit v, V.unsafeLast v)+  {-# INLINE _Snoc #-}++instance Reversing (Vector a) where+  reversing = V.reverse++-- | Analogous to 'Data.Vector.Lens.sliced'.+sliced :: Int -- ^ @i@ starting index+       -> Int -- ^ @n@ length+       -> Lens' (Vector a) (Vector a)+sliced i n f v = f (V.slice i n v) <&> \ v0 -> v V.// zip [i..i+n-1] (V.toList v0)+{-# INLINE sliced #-}++-- | Analogous to 'Data.Vector.Lens.toVectorOf'.+toVectorOf :: Getting (Endo [a]) s a -> s -> Vector a+toVectorOf l s = V.fromList (toListOf l s)+{-# INLINE toVectorOf #-}++-- | Analogous to 'Data.Vector.Lens.vector'.+vector :: Iso [a] [b] (Vector a) (Vector b)+vector = iso V.fromList V.toList+{-# INLINE vector #-}++-- | Analogous to 'Data.Vector.Lens.forced'.+forced :: Iso (Vector a) (Vector b) (Vector a) (Vector b)+forced = iso V.force V.force+{-# INLINE forced #-}++-- | Analogous to 'Data.Vector.Lens.ordinals'.+ordinals :: [Int] -> IndexedTraversal' Int (Vector a) a+ordinals is f v = fmap (v V.//) $ traverse (\i -> (,) i <$> indexed f i (v V.! i)) $ ordinalNub (length v) is+{-# INLINE ordinals #-}
+ strict-containers-lens.cabal view
@@ -0,0 +1,41 @@+Name:           strict-containers-lens+Version:        0.1+Synopsis:       Strict containers - Lens instances+Category:       Data, Data Structures, Lenses+Description:+  This package provides @lens@ utilities and instances for @strict-containers@.+License:        BSD3+License-File:   LICENSE+Maintainer:     Ximin Luo <infinity0@pwned.gg>+Copyright:      (c) 2021 by Ximin Luo+Homepage:       https://github.com/haskellari/strict-containers+Cabal-Version: >= 1.10+Build-type:     Simple+extra-source-files:+    CHANGELOG.md+tested-with:+  GHC ==8.2.2+   || ==8.4.4+   || ==8.6.5+   || ==8.8.3+   || ==8.10.4+   || ==9.0.1++library+  default-language: Haskell2010+  hs-source-dirs:   src+  ghc-options:      -Wall++  build-depends:+      base                  >= 4.5.0.0  && < 5+    , hashable              >= 1.2.7.0  && < 1.4+    , strict-containers     >= 0.1+    , lens                  >= 4.19     && < 6++  exposed-modules:+    Data.Strict.Containers.Lens+    Data.Strict.HashMap.Lens+    Data.Strict.IntMap.Lens+    Data.Strict.Map.Lens+    Data.Strict.Sequence.Lens+    Data.Strict.Vector.Lens