packages feed

lens-witherable 0.1.1.0 → 0.2.0.0

raw patch · 3 files changed

+152/−28 lines, 3 filesdep +containersdep +hashabledep +transformersPVP ok

version bump matches the API change (PVP)

Dependencies added: containers, hashable, transformers, unordered-containers

API changes (from Hackage documentation)

- Witherable.Lens: filterOfA :: Applicative f => ((a -> Withering f a) -> s -> f s) -> (a -> f Bool) -> s -> f s
- Witherable.Lens: infix 2 `witherOf`
+ Witherable.Lens: catMaybesOf :: ((Maybe a -> Withering Identity a) -> s -> Identity t) -> s -> t
+ Witherable.Lens: filterAOf :: Applicative f => ((a -> Withering f a) -> s -> f s) -> (a -> f Bool) -> s -> f s
+ Witherable.Lens: forMaybeOf :: ((a -> Withering f b) -> s -> f t) -> s -> (a -> f (Maybe b)) -> f t
+ Witherable.Lens: hashNubOf :: (Eq a, Hashable a) => ((a -> Withering (State (HashSet a)) a) -> s -> State (HashSet a) s) -> s -> s
+ Witherable.Lens: hashNubOnOf :: (Eq b, Hashable b) => ((a -> Withering (State (HashSet b)) a) -> s -> State (HashSet b) s) -> (a -> b) -> s -> s
+ Witherable.Lens: ordNubOf :: Ord a => ((a -> Withering (State (Set a)) a) -> s -> State (Set a) s) -> s -> s
+ Witherable.Lens: ordNubOnOf :: Ord b => ((a -> Withering (State (Set b)) a) -> s -> State (Set b) s) -> (a -> b) -> s -> s

Files

CHANGELOG.md view
@@ -1,5 +1,9 @@ # Revision history for lens-witherable +## 0.2.0.0 -- 2024-03-10++* Rename filterOfA -> filterAOf, port over deprecated lenslike functions from witherable+ ## 0.1.1.0 -- 2024-03-10  * Add filterOfA, some doc cleanups.
lens-witherable.cabal view
@@ -1,6 +1,6 @@ cabal-version:        2.4 name:                 lens-witherable-version:              0.1.1.0+version:              0.2.0.0 synopsis:             lens-compatible tools for working with witherable copyright:            Copyright (C) 2021-2022 Carl Howells license:              MIT@@ -14,6 +14,7 @@             Provides tools for integrating the witherable package with lens             combinators. See README.md for more details. + extra-source-files:   CHANGELOG.md,                       README.md @@ -26,12 +27,16 @@      if flag(top-level-witherable)        build-depends: witherable >=0.4 && <0.5,-                      base >=4.10 && <5,+                      base >=4.10 && <5     else        build-depends: witherable >=0 && <0.5,                       base >=4.10 && <4.16        mixins:        witherable (Data.Witherable as Witherable) +    build-depends:    containers >=0.5 && <0.8,+                      unordered-containers >=0.2.12.0 && <0.3,+                      hashable >=1.2.7.0 && <1.5,+                      transformers >=0.5.2.0 && <0.7  flag top-level-witherable     description:      Import Witherable instead of Data.Witherable
src/Witherable/Lens.hs view
@@ -15,7 +15,16 @@  import Witherable.Lens.Withering +import Control.Monad.Trans.State.Strict (State, evalState, gets, modify') +import Data.Set (Set)+import qualified Data.Set as S++import Data.Hashable (Hashable)+import Data.HashSet (HashSet)+import qualified Data.HashSet as H++ -- | A variant on 'traverse' that allows the targets to be filtered -- out of the 'Witherable' structure. Note that this introduces a -- change in types down the lens composition chain, which means that@@ -72,8 +81,79 @@     | otherwise = empty  ++--------------------------------------------------------+-- Port deprecated definitions over from Data.Witherable++-- | Transform and effectfully filter elements matched by a specific+-- 'Withering' context, a la 'wither'.+--+-- >>> witherOf (withered . _1) (\x -> do b <- readLn ; if b then pure (Just (show x)) else pure Nothing) [(1,2),(2,3),(3,4)]+-- False+-- True+-- True+-- [("2",3),("3",4)]+witherOf+    :: ((a -> Withering f b) -> s -> f t)+    -> (a -> f (Maybe b)) -> s -> f t+witherOf w p = w (Withering . p)++-- | A version of 'witherOf' with arguments re-arranged.+forMaybeOf+    :: ((a -> Withering f b) -> s -> f t)+    -> s -> (a -> f (Maybe b)) -> f t+forMaybeOf w s p = witherOf w p s++-- | Transform and filter elements matched by a specific 'Withering'+-- context, a la 'Data.Maybe.mapMaybe'. See 'witherOf' for a more+-- flexible version that works within arbitrary 'Applicative' effects.+--+-- >>> mapMaybeOf (withered . _1) (\x -> if even x then Just (show x) else Nothing) [(1,2),(2,4),(3,6),(4,8)]+-- [("2",4),("4",8)]+mapMaybeOf+    :: ((a -> Withering Identity b) -> s -> Identity t)+    -> (a -> Maybe b) -> s -> t+mapMaybeOf w p = runIdentity . w (Withering . pure . p)++-- | Filter @Nothing@ values out of a structure, like+-- 'Data.Maybe.catMaybes'.+--+-- >>> catMaybesOf withered [Just 1, Nothing, Just 2]+-- [1,2]+--+-- >>> catMaybesOf (withered . _2) [("a", Just 1), ("b", Nothing), ("c", Just 2)]+-- [("a",1),("c",2)]+catMaybesOf+    :: ((Maybe a -> Withering Identity a) -> s -> Identity t)+    -> s -> t+catMaybesOf w = runIdentity . w toWithering+  where+    toWithering Nothing = empty+    toWithering (Just x) = pure x+ -- | Remove elements matched by a specific 'Withering' context if they+-- don't match a predicate returning a result in an arbitrary+-- Applicative context.+--+-- >>> filterAOf (withered . _1) (const readLn) [(1,2),(2,4),(3,6),(4,8)]+-- False+-- True+-- True+-- False+-- [(2,4),(3,6)]+filterAOf+    :: Applicative f+    => ((a -> Withering f a) -> s -> f s)+    -> (a -> f Bool) -> s -> f s+filterAOf w p = w toWitheringA+  where+    toWitheringA a = Withering $ (\x -> if x then Just a else Nothing) <$> p a++-- | Remove elements matched by a specific 'Withering' context if they -- don't match a predicate.+--+-- >>> filterOf (withered . _1) even [(1,2),(2,4),(3,6),(4,8)]+-- [(2,4),(4,8)] filterOf     :: ((a -> Withering Identity a) -> s -> Identity s)     -> (a -> Bool) -> s -> s@@ -82,33 +162,68 @@     toWithering a         | p a = pure a         | otherwise = empty-infix 2 `filterOf` --- | Remove elements matched by a specific 'Withering' context if they--- don't match a predicate returning a result in an arbitrary--- Applicative context.-filterOfA-    :: Applicative f-    => ((a -> Withering f a) -> s -> f s)-    -> (a -> f Bool) -> s -> f s-filterOfA w p = w toWitheringA+-- | Removes duplicates from a structure based on the focused element.+--+-- >>> ordNubOf (traverse . withered . _2) [[("z",3),("q",3)],[("apple", 1), ("bat", 1), ("cat", 2), ("dog", 2)]]+-- [[("z",3)],[("apple",1),("cat",2)]]+ordNubOf+    :: Ord a+    => ((a -> Withering (State (Set a)) a) -> s -> State (Set a) s)+    -> s -> s+ordNubOf w = ordNubOnOf w id++-- | Removes duplicates from a structure based on applying a function+-- to the focused element.+--+-- >>> ordNubOnOf (withered . _2) (`div` 2) [("apple", 1), ("bat", 2), ("cat", 3), ("dog", 4)]+-- [("apple",1),("bat",2),("dog",4)]+ordNubOnOf+    :: Ord b+    => ((a -> Withering (State (Set b)) a) -> s -> State (Set b) s)+    -> (a -> b)+    -> s -> s+ordNubOnOf w f s = evalState (w doWithering s) S.empty   where-    toWitheringA a = Withering $ (\x -> if x then Just a else Nothing) <$> p a-infix 2 `filterOfA`+    doWithering x = Withering $ do+        let fx = f x+        seen <- gets (S.member fx)+        if seen+            then pure Nothing+            else do+                modify' (S.insert fx)+                pure (Just x) --- | Transform and filter elements matched by a specific 'Withering'--- context, a la 'Data.Maybe.mapMaybe'. See 'witherOf' for a more--- flexible version that works within arbitrary 'Applicative' effects.-mapMaybeOf-    :: ((a -> Withering Identity b) -> s -> Identity t)-    -> (a -> Maybe b) -> s -> t-mapMaybeOf w p = runIdentity . w (Withering . pure . p)-infix 2 `mapMaybeOf`+-- | Removes duplicates from a structure based on the focused+-- element. Often will be more efficient than 'ordNubOf' if your data+-- type supports 'Hashable'+--+-- >>> hashNubOf (traverse . withered . _2) [[("z",3),("q",3)],[("apple", 1), ("bat", 1), ("cat", 2), ("dog", 2)]]+-- [[("z",3)],[("apple",1),("cat",2)]]+hashNubOf+    :: (Eq a, Hashable a)+    => ((a -> Withering (State (HashSet a)) a) -> s -> State (HashSet a) s)+    -> s -> s+hashNubOf w = hashNubOnOf w id --- | Transform and effectfully filter elements matched by a specific--- 'Withering' context, a la 'wither'.-witherOf-    :: ((a -> Withering f b) -> s -> f t)-    -> (a -> f (Maybe b)) -> s -> f t-witherOf w p = w (Withering . p)-infix 2 `witherOf`+-- | Removes duplicates from a structure based on applying a function+-- to the focused element. Often will be more efficient than+-- 'ordNubOnOf' if your data type supports 'Hashable'+--+-- >>> hashNubOnOf (withered . _2) (`div` 2) [("apple", 1), ("bat", 2), ("cat", 3), ("dog", 4)]+-- [("apple",1),("bat",2),("dog",4)]+hashNubOnOf+    :: (Eq b, Hashable b)+    => ((a -> Withering (State (HashSet b)) a) -> s -> State (HashSet b) s)+    -> (a -> b)+    -> s -> s+hashNubOnOf w f s = evalState (w doWithering s) H.empty+  where+    doWithering x = Withering $ do+        let fx = f x+        seen <- gets (H.member fx)+        if seen+            then pure Nothing+            else do+                modify' (H.insert fx)+                pure (Just x)