packages feed

microlens 0.3.3.0 → 0.3.4.0

raw patch · 4 files changed

+88/−6 lines, 4 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ Lens.Micro: non :: Eq a => a -> Lens' (Maybe a) a
- Lens.Micro.Internal: foldring :: (Applicative (Const r)) => ((a -> Const r a -> Const r a) -> Const r a -> s -> Const r a) -> (a -> Const r b) -> s -> Const r t
+ Lens.Micro.Internal: foldring :: Applicative (Const r) => ((a -> Const r a -> Const r a) -> Const r a -> s -> Const r a) -> (a -> Const r b) -> s -> Const r t

Files

CHANGELOG.md view
@@ -1,3 +1,7 @@+# 0.3.4.0++* Added `non`.+ # 0.3.3.0  * Added `filtered`.
microlens.cabal view
@@ -1,5 +1,5 @@ name:                microlens-version:             0.3.3.0+version:             0.3.4.0 synopsis:            A tiny part of the lens library which you can depend upon description:   This is an extract from <http://hackage.haskell.org/package/lens lens> (with no dependencies). It's not a toy lenses library, unsuitable for “real world”, but merely a small one. It is compatible with lens, and should have same performance. It also has better documentation.
src/Lens/Micro.hs view
@@ -40,6 +40,7 @@   Lens, Lens',   lens,   at,+  non,   _1, _2, _3, _4, _5,    -- * Traversals (lenses iterating over several elements)@@ -70,6 +71,7 @@ import Control.Monad import Data.Functor.Identity import Data.Monoid+import Data.Maybe  #if __GLASGOW_HASKELL__ >= 710 import Data.Function ((&))@@ -483,6 +485,80 @@ lens sa sbt afb s = sbt s <$> afb (sa s) {-# INLINE lens #-} +{- |+'non' lets you “relabel” a 'Maybe' by equating 'Nothing' to an arbitrary value (which you can choose):++>>> Just 1 ^. non 0+1++>>> Nothing ^. non 0+0++The most useful thing about 'non' is that relabeling also works in other direction. If you try to 'set' the “forbidden” value, it'll be turned to 'Nothing':++>>> Just 1 & non 0 .~ 0+Nothing++Setting anything else works just fine:++>>> Just 1 & non 0 .~ 5+Just 5++Same happens if you try to modify a value:++>>> Just 1 & non 0 %~ subtract 1+Nothing++>>> Just 1 & non 0 .~ (+ 1)+Just 2++'non' is often useful when combined with 'at'. For instance, if you have a map of songs and their playcounts, it makes sense not to store songs with 0 plays in the map; 'non' can act as a filter that wouldn't pass such entries.++Decrease playcount of a song to 0, and it'll be gone:++>>> fromList [("Soon",1),("Yesterday",3)] & at "Soon" . non 0 %~ subtract 1+fromList [("Yesterday",3)]++Try to add a song with 0 plays, and it won't be added:++>>> fromList [("Yesterday",3)] & at "Soon" . non 0 .~ 0+fromList [("Yesterday",3)]++But it will be added if you set any other number:++>>> fromList [("Yesterday",3)] & at "Soon" . non 0 .~ 1+fromList [("Soon",1),("Yesterday",3)]++'non' is also useful when working with nested maps. Here a nested map is created when it's missing:++>>> Map.empty & at "Dez Mona" . non Map.empty . at "Soon" .~ Just 1+fromList [("Dez Mona",fromList [("Soon",1)])]++and here it is deleted when its last entry is deleted (notice that 'non' is used twice here):++>>> fromList [("Dez Mona",fromList [("Soon",1)])] & at "Dez Mona" . non Map.empty . at "Soon" . non 0 %~ subtract 1+fromList []++To understand the last example better, observe the flow of values in it:++* the map goes into @at \"Dez Mona\"@+* the nested map (wrapped into @Just@) goes into @non Map.empty@+* @Just@ is unwrapped and the nested map goes into @at \"Soon\"@+* @Just 1@ is unwrapped by @non 0@++Then the final value – i.e. 1 – is modified by @subtract 1@ and the result (which is 0) starts flowing backwards:++* @non 0@ sees the 0 and produces a @Nothing@+* @at \"Soon\"@ sees @Nothing@ and deletes the corresponding value from the map+* the resulting empty map is passed to @non Map.empty@, which sees that it's empty and thus produces @Nothing@+* @at \"Dez Mona\"@ sees @Nothing@ and removes the key from the map++-}+non :: Eq a => a -> Lens' (Maybe a) a+non x afb s = f <$> afb (fromMaybe x s)+  where f y = if x == y then Nothing else Just y+{-# INLINE non #-}+ -- Traversals --------------------------------------------------------------  {- |@@ -620,7 +696,7 @@ >>> [] ^? _head Nothing -This package only lets you use '_head' on lists, but you can import @Lens.Micro.GHC@ from the <http://hackage.haskell.org/package/microlens-ghc microlens-ghc> package and get instances for @ByteString@ and @Seq@.+This package only lets you use '_head' on lists, but you can use @Lens.Micro.GHC@ from <http://hackage.haskell.org/package/microlens-ghc microlens-ghc> and get instances for @ByteString@ and @Seq@, or use @Lens.Micro.Platform@ from <http://hackage.haskell.org/package/microlens-platform microlens-platform> and additionally get instances for @Text@ and @Vector@. -} _head :: Cons s s a a => Traversal' s a _head = _Cons._1@@ -650,7 +726,7 @@ >>> "I HATE CAPS." & _tail.each %~ toLower "I hate caps." -This package only lets you use '_tail' on lists, but you can import @Lens.Micro.GHC@ from the <http://hackage.haskell.org/package/microlens-ghc microlens-ghc> package and get instances for @ByteString@ and @Seq@.+This package only lets you use '_tail' on lists, but you can use @Lens.Micro.GHC@ from <http://hackage.haskell.org/package/microlens-ghc microlens-ghc> and get instances for @ByteString@ and @Seq@, or use @Lens.Micro.Platform@ from <http://hackage.haskell.org/package/microlens-platform microlens-platform> and additionally get instances for @Text@ and @Vector@. -} _tail :: Cons s s a a => Traversal' s s _tail = _Cons._2
src/Lens/Micro/Internal.hs view
@@ -175,7 +175,7 @@ 'each' :: ('RealFloat' a, 'RealFloat' b) => 'Traversal' ('Complex' a) ('Complex' b) a b @ -Additionally, you can use 'each' with types from <http://hackage.haskell.org/package/array array>, <http://hackage.haskell.org/package/bytestring bytestring>, and <http://hackage.haskell.org/package/containers containers> by importing @Lens.Micro.GHC@ from the <http://hackage.haskell.org/package/microlens-ghc microlens-ghc> package.+Additionally, you can use 'each' with types from <http://hackage.haskell.org/package/array array>, <http://hackage.haskell.org/package/bytestring bytestring>, and <http://hackage.haskell.org/package/containers containers> by using @Lens.Micro.GHC@ from <http://hackage.haskell.org/package/microlens-ghc microlens-ghc>, or with types from <http://hackage.haskell.org/package/vector vector>, <http://hackage.haskell.org/package/text text>, and <http://hackage.haskell.org/package/unordered-containers unordered-containers> by using @Lens.Micro.Platform@ from <http://hackage.haskell.org/package/microlens-platform microlens-platform>.   -}   each :: Traversal s t a b   default each :: (Traversable g, s ~ g a, t ~ g b) => Traversal s t a b@@ -249,7 +249,7 @@ 'ix' :: ('Eq' e) => e -> 'Traversal'' (e -> a) a @ -Additionally, you can use 'ix' with types from <http://hackage.haskell.org/package/array array>, <http://hackage.haskell.org/package/bytestring bytestring>, and <http://hackage.haskell.org/package/containers containers> by importing @Lens.Micro.GHC@ from the <http://hackage.haskell.org/package/microlens-ghc microlens-ghc> package.+Additionally, you can use 'ix' with types from <http://hackage.haskell.org/package/array array>, <http://hackage.haskell.org/package/bytestring bytestring>, and <http://hackage.haskell.org/package/containers containers> by using @Lens.Micro.GHC@ from <http://hackage.haskell.org/package/microlens-ghc microlens-ghc>, or with types from <http://hackage.haskell.org/package/vector vector>, <http://hackage.haskell.org/package/text text>, and <http://hackage.haskell.org/package/unordered-containers unordered-containers> by using @Lens.Micro.Platform@ from <http://hackage.haskell.org/package/microlens-platform microlens-platform>.   -}   ix :: Index m -> Traversal' m (IxValue m)   default ix :: (At m) => Index m -> Traversal' m (IxValue m)@@ -276,6 +276,8 @@  If you want to modify an already existing value, you should use 'ix' instead because then you won't have to deal with 'Maybe' ('ix' is available for all types that have 'at'). +'at' is often used with 'Lens.Micro.non'.+ Note that 'at' isn't strict for @Map@, even if you're using @Data.Map.Strict@:  >>> Data.Map.Strict.size (Data.Map.Strict.empty & at 1 .~ Just undefined)@@ -283,7 +285,7 @@  The reason for such behavior is that there's actually no “strict @Map@” type; @Data.Map.Strict@ just provides some strict functions for ordinary @Map@s. -This package doesn't actually provide any instances for 'at', but you can import @Lens.Micro.GHC@ from the <http://hackage.haskell.org/package/microlens-ghc microlens-ghc> package and get instances for @Map@ and @IntMap@.+This package doesn't actually provide any instances for 'at', but there are instances for @Map@ and @IntMap@ in <http://hackage.haskell.org/package/microlens-ghc microlens-ghc> and an instance for @HashMap@ in <http://hackage.haskell.org/package/microlens-platform microlens-platform>.   -}   at :: Index m -> Lens' m (Maybe (IxValue m))