Skip to content

Commit

Permalink
Added non, renamed (%) to (&) due to clash with folks about the cla…
Browse files Browse the repository at this point in the history
…sh with Data.Ratio.
  • Loading branch information
ekmett committed Nov 20, 2012
1 parent 28927b2 commit 2ec2d3b
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 38 deletions.
24 changes: 12 additions & 12 deletions src/Control/Lens/Getter.hs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ module Control.Lens.Getter
, to
-- * Combinators for Getters and Folds
, (^.), (^$)
, (%), (^%)
, (&), (^&)
, view
, views
, use
Expand All @@ -74,8 +74,8 @@ import Control.Monad.State.Class as State
-- $setup
-- >>> import Control.Lens

infixl 8 ^., ^%
infixl 1 %
infixl 8 ^., ^&
infixl 1 &
infixr 0 ^$

-------------------------------------------------------------------------------
Expand All @@ -88,21 +88,21 @@ infixr 0 ^$
-- for inference. Here it is supplied for notational convenience and given a precedence that allows it
-- to be nested inside uses of ('$').
--
-- >>> "hello" % length % succ
-- >>> "hello" & length & succ
-- 6
(%) :: a -> (a -> b) -> b
a % f = f a
{-# INLINE (%) #-}
(&) :: a -> (a -> b) -> b
a & f = f a
{-# INLINE (&) #-}

-- | A version of ('Control.Lens.Combinators.%') with much tighter precedence that can be interleaved with ('^.')
-- | A version of ('&') with much tighter precedence that can be interleaved with ('^.')
--
-- >>> "hello"^%length
-- >>> "hello" ^& length
-- 5
-- >>> import Data.List.Lens
-- >>> ("hello","world")^._1^%reverse^._head
-- >>> ("hello","world")^._1^&reverse^._head
-- 'o'
(^%) :: a -> (a -> b) -> b
a ^% f = f a
(^&) :: a -> (a -> b) -> b
a ^& f = f a

-------------------------------------------------------------------------------
-- Getters
Expand Down
29 changes: 28 additions & 1 deletion src/Control/Lens/Iso.hs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ module Control.Lens.Iso
, _const
, identity
, simple
, non
-- * Storing Isomorphisms
, ReifiedIso(..)
-- * Simplicity
Expand All @@ -46,10 +47,12 @@ import Control.Lens.Isomorphic
import Control.Lens.Setter
import Control.Lens.Type
import Data.Functor.Identity
import Data.Maybe (fromMaybe)
import Prelude hiding ((.),id)

-- $setup
-- >>> import Control.Lens
-- >>> import Data.Map as Map

-----------------------------------------------------------------------------
-- Isomorphisms families as Lenses
Expand Down Expand Up @@ -167,14 +170,38 @@ mapping :: Functor f => SimpleIso s a -> SimpleIso (f s) (f a)
mapping l = iso (view l <$>) (view (from l) <$>)
{-# INLINE mapping #-}


-- | Composition with this isomorphism is occasionally useful when your 'Lens',
-- 'Control.Lens.Traversal.Traversal' or 'Iso' has a constraint on an unused
-- argument to force that argument to agree with the
-- type of a used argument and avoid @ScopedTypeVariables@ or other ugliness.
simple :: Iso a b a b
simple = isos id id id id

-- | If @v@ is an element of a type @a@, and @a'@ is @a@ sans the element @v@, then @non v@ is an isomorphism from
-- @Maybe a'@ to @a@.
--
-- This is practically quite useful when you want to have a map where all the entries should have non-zero values.
--
-- >>> Map.fromList [("hello",1)] & at "hello" . non 0 +~ 2
-- fromList [("hello",3)]
--
-- >>> Map.fromList [("hello",1)] & at "hello" . non 0 -~ 1
-- fromList []
--
-- >>> Map.fromList [("hello",1)] ^. at "hello" . non 0
-- 1
--
-- >>> Map.fromList [] ^. at "hello" . non 0
-- 0

non :: a -> Simple Iso (Maybe a) a
non a = iso (fromMaybe a) go where
go b | a == b = Nothing
| otherwise = Just b


non v f s = go <$> f (fromMaybe v s) where go v' = if v' == v then Nothing else Just v'

-----------------------------------------------------------------------------
-- Reifying Isomorphisms
-----------------------------------------------------------------------------
Expand Down
34 changes: 17 additions & 17 deletions src/Control/Lens/TH.hs
Original file line number Diff line number Diff line change
Expand Up @@ -186,21 +186,21 @@ defaultRules = LensRules top field (const Nothing) $
-- for isomorphisms and traversals, and not making any classes.
lensRules :: LensRules
lensRules = defaultRules
% lensIso .~ const Nothing
% lensClass .~ const Nothing
% handleSingletons .~ True
% partialLenses .~ False
% buildTraversals .~ True
& lensIso .~ const Nothing
& lensClass .~ const Nothing
& handleSingletons .~ True
& partialLenses .~ False
& buildTraversals .~ True

-- | Rules for making lenses and traversals that precompose another lens.
classyRules :: LensRules
classyRules = defaultRules
% lensIso .~ const Nothing
% handleSingletons .~ False
% lensClass .~ classy
% classRequired .~ True
% partialLenses .~ False
% buildTraversals .~ True
& lensIso .~ const Nothing
& handleSingletons .~ False
& lensClass .~ classy
& classRequired .~ True
& partialLenses .~ False
& buildTraversals .~ True
where
classy :: String -> Maybe (String, String)
classy n@(a:as) = Just ("Has" ++ n, toLower a:as)
Expand All @@ -209,9 +209,9 @@ classyRules = defaultRules
-- | Rules for making an isomorphism from a data type
isoRules :: LensRules
isoRules = defaultRules
% handleSingletons .~ True
% singletonRequired .~ True
% singletonAndField .~ True
& handleSingletons .~ True
& singletonRequired .~ True
& singletonAndField .~ True

-- | Build lenses (and traversals) with a sensible default configuration.
--
Expand Down Expand Up @@ -271,7 +271,7 @@ makeIso = makeLensesWith isoRules
-- > makeLensesFor [("_foo", "fooLens"), ("baz", "lbaz")] ''Foo
-- > makeLensesFor [("_barX", "bar"), ("_barY", "bar)] ''Bar
makeLensesFor :: [(String, String)] -> Name -> Q [Dec]
makeLensesFor fields = makeLensesWith $ lensRules % lensField .~ (`Prelude.lookup` fields)
makeLensesFor fields = makeLensesWith $ lensRules & lensField .~ (`Prelude.lookup` fields)

-- | Derive lenses and traversals, using a named wrapper class, and specifying
-- explicit pairings of @(fieldName, traversalName)@.
Expand All @@ -281,8 +281,8 @@ makeLensesFor fields = makeLensesWith $ lensRules % lensField .~ (`Prelude.looku
-- > makeClassyFor "HasFoo" "foo" [("_foo", "fooLens"), ("bar", "lbar")] ''Foo
makeClassyFor :: String -> String -> [(String, String)] -> Name -> Q [Dec]
makeClassyFor clsName funName fields = makeLensesWith $ classyRules
% lensClass .~ const (Just (clsName,funName))
% lensField .~ (`Prelude.lookup` fields)
& lensClass .~ const (Just (clsName,funName))
& lensField .~ (`Prelude.lookup` fields)

-- | Build lenses with a custom configuration.
makeLensesWith :: LensRules -> Name -> Q [Dec]
Expand Down
2 changes: 1 addition & 1 deletion src/Control/Lens/Zipper.hs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
-- Since individual levels of a zipper are managed by an arbitrary 'Traversal',
-- you can move left and right through the 'Traversal' selecting neighboring elements.
--
-- >>> zipper ("hello","world") % down _1 % fromWithin traverse % focus .~ 'J' % rightmost % focus .~ 'y' % rezip
-- >>> zipper ("hello","world") & down _1 & fromWithin traverse & focus .~ 'J' & rightmost & focus .~ 'y' & rezip
-- ("Jelly","world")
--
-- This is particularly powerful when compiled with 'Control.Lens.Plated.plate',
Expand Down
10 changes: 3 additions & 7 deletions src/Data/Monoid/Lens.hs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ import Data.Monoid
import Control.Lens
import Control.Monad.State.Class as State

-- $setup
-- >>> :m + Control.Lens Data.Monoid.Lens Data.Foldable

infixr 4 <>~, <<>~
infix 4 <>=, <<>=

-- | Modify the target of a monoidally valued by 'mappend'ing another value.
--
-- >>> :m + Control.Lens
-- >>> both <>~ "!!!" $ ("hello","world")
-- ("hello!!!","world!!!")
--
Expand Down Expand Up @@ -78,11 +80,9 @@ _endo = isos Endo appEndo Endo appEndo

-- | Isomorphism for 'All'
--
-- >>> :m + Control.Lens Data.Monoid.Lens Data.Foldable
-- >>> ala _all foldMap [True,True]
-- True
--
-- >>> :m + Control.Lens Data.Monoid.Lens Data.Foldable
-- >>> ala _all foldMap [True,False]
-- False
_all :: Simple Iso Bool All
Expand All @@ -91,11 +91,9 @@ _all = iso All getAll

-- | Isomorphism for 'Any'
--
-- >>> :m + Control.Lens Data.Monoid.Lens Data.Foldable
-- >>> ala _any foldMap [False,False]
-- False
--
-- >>> :m + Control.Lens Data.Monoid.Lens Data.Foldable
-- >>> ala _any foldMap [True,False]
-- True
_any :: Simple Iso Bool Any
Expand All @@ -104,7 +102,6 @@ _any = iso Any getAny

-- | Isomorphism for 'Sum'
--
-- >>> :m + Control.Lens Data.Monoid.Lens Data.Foldable
-- >>> ala _sum foldMap [1,2,3,4]
-- 10
_sum :: Iso a b (Sum a) (Sum b)
Expand All @@ -113,7 +110,6 @@ _sum = isos Sum getSum Sum getSum

-- | Isomorphism for 'Product'
--
-- >>> :m + Control.Lens Data.Monoid.Lens Data.Foldable
-- >>> ala _product foldMap [1,2,3,4]
-- 24
_product :: Iso a b (Product a) (Product b)
Expand Down

0 comments on commit 2ec2d3b

Please sign in to comment.