Skip to content

Commit 83a242f

Browse files
Merge pull request #96 from LiamGoodacre/feature/sum-lens
Support inverse of `lens'`
2 parents afe51d4 + 111b3de commit 83a242f

File tree

3 files changed

+32
-2
lines changed

3 files changed

+32
-2
lines changed

src/Data/Lens.purs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ module Data.Lens
2525

2626
import Data.Lens.Iso (AnIso, AnIso', Iso, Iso', Optic, Exchange(..), Re(..), au, auf, cloneIso, non, curried, flipped, iso, re, uncurried, under, withIso)
2727
import Data.Lens.Grate (Grate, Grate', zipWithOf, zipFWithOf, collectOf)
28-
import Data.Lens.Lens (ALens, ALens', Lens, Lens', cloneLens, lens, lens', withLens)
28+
import Data.Lens.Lens (ALens, ALens', Lens, Lens', cloneLens, lens, lens', withLens, lensStore)
2929
import Data.Lens.Prism (APrism, APrism', Prism, Prism', Review, Review', clonePrism, is, isn't, matching, nearly, only, prism, prism', review, withPrism)
3030
import Data.Lens.Traversal (Traversal, Traversal', element, elementsOf, failover, itraverseOf, sequenceOf, traverseOf, traversed)
3131
import Data.Lens.Types (class Wander, ALens, ALens', APrism, APrism', AnIso, AnIso', ATraversal, ATraversal', Fold, Fold', Getter, Getter', AGetter, AGetter', IndexedFold, IndexedFold', IndexedGetter, IndexedGetter', IndexedOptic, IndexedOptic', IndexedSetter, IndexedSetter', IndexedTraversal, IndexedTraversal', Iso, Iso', Lens, Lens', Optic, Optic', Prism, Prism', Review, Review', Setter, Setter', Traversal, Traversal', Exchange(..), Forget(..), Indexed(..), Market(..), Re(..), Shop(..), Tagged(..), wander)

src/Data/Lens/Lens.purs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ module Data.Lens.Lens
88
, ilens'
99
, withIndexedLens
1010
, cloneIndexedLens
11+
, lensStore
1112
, module Data.Lens.Types
1213
) where
1314

1415
import Prelude
1516

17+
import Control.Apply (lift2)
1618
import Data.Lens.Internal.Shop (Shop(..))
1719
import Data.Lens.Internal.Indexed (Indexed(..))
1820
import Data.Lens.Types
@@ -64,3 +66,23 @@ withIndexedLens l f = case l (Indexed (Shop identity \_ b -> b)) of Shop x y ->
6466

6567
cloneIndexedLens :: forall i s t a b. AnIndexedLens i s t a b -> IndexedLens i s t a b
6668
cloneIndexedLens l = withIndexedLens l \x y p -> ilens x y p
69+
70+
-- | Converts a lens into the form that `lens'` accepts.
71+
-- |
72+
-- | Can be useful when defining a lens where the focus appears under multiple
73+
-- | constructors of an algebraic data type. This function would be called for
74+
-- | each case of the data type.
75+
-- |
76+
-- | For example:
77+
-- |
78+
-- | ```
79+
-- | data LensStoreExample = LensStoreA Int | LensStoreB (Tuple Boolean Int)
80+
-- |
81+
-- | lensStoreExampleInt :: Lens' LensStoreExample Int
82+
-- | lensStoreExampleInt = lens' case _ of
83+
-- | LensStoreA i -> map LensStoreA <$> lensStore identity i
84+
-- | LensStoreB i -> map LensStoreB <$> lensStore _2 i
85+
-- | ```
86+
lensStore :: forall s t a b . ALens s t a b -> s -> Tuple a (b -> t)
87+
lensStore l = withLens l (lift2 Tuple)
88+

test/Main.purs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import Prelude
55
import Control.Monad.State (evalState, get)
66
import Data.Distributive (class Distributive)
77
import Data.Either (Either(..))
8-
import Data.Lens (Getter', Prism', _1, _2, _Just, _Left, collectOf, lens, preview, prism', takeBoth, toArrayOf, traversed, view)
8+
import Data.Lens (Getter', Prism', _1, _2, _Just, _Left, collectOf, lens, lens', preview, prism', takeBoth, toArrayOf, traversed, view, lensStore)
99
import Data.Lens.Fold ((^?))
1010
import Data.Lens.Fold.Partial ((^?!), (^@?!))
1111
import Data.Lens.Grate (Grate, cloneGrate, grate, zipWithOf)
@@ -121,6 +121,14 @@ cloneTraversalTest =
121121
wrapper = { traversal: t }
122122
in preview (cloneTraversal wrapper.traversal) [ 0, 1, 2 ]
123123

124+
-- lensStore example
125+
data LensStoreExample = LensStoreA Int | LensStoreB (Tuple Boolean Int)
126+
127+
lensStoreExampleInt :: Lens' LensStoreExample Int
128+
lensStoreExampleInt = lens' case _ of
129+
LensStoreA i -> map LensStoreA <$> lensStore identity i
130+
LensStoreB i -> map LensStoreB <$> lensStore _2 i
131+
124132
main :: Effect Unit
125133
main = do
126134
logShow $ view bars doc

0 commit comments

Comments
 (0)