Skip to content

Commit 4206727

Browse files
committed
Add ATraversal and cloneTraversal
Based on code from #26, but doesn't use the Lens library for the traversals. Follows Shop for overall organization. Fixes #26.
1 parent 3788b39 commit 4206727

File tree

4 files changed

+54
-5
lines changed

4 files changed

+54
-5
lines changed

src/Data/Lens/Internal/Bazaar.purs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
module Data.Lens.Internal.Bazaar where
2+
3+
import Prelude
4+
5+
import Data.Bitraversable (bitraverse)
6+
import Data.Lens.Internal.Wander (class Wander)
7+
import Data.Profunctor (class Profunctor)
8+
import Data.Profunctor.Choice (class Choice)
9+
import Data.Profunctor.Strong (class Strong)
10+
import Data.Traversable (traverse)
11+
import Data.Tuple (Tuple(..))
12+
13+
-- | This is used to characterize a Traversal.
14+
newtype Bazaar p a b s t = Bazaar (forall f. Applicative f => p a (f b) -> s -> f t)
15+
16+
runBazaar :: forall p a b s t. Bazaar p a b s t -> (forall f. Applicative f => p a (f b) -> s -> f t)
17+
runBazaar (Bazaar x) = x
18+
19+
instance profunctorBazaar :: Profunctor (Bazaar p a b) where
20+
dimap f g (Bazaar b) = Bazaar \pafb s -> g <$> b pafb (f s)
21+
22+
instance strongBazaar :: Strong (Bazaar p a b) where
23+
first (Bazaar b) = Bazaar (\pafb (Tuple x y) -> flip Tuple y <$> b pafb x)
24+
second (Bazaar b) = Bazaar (\pafb (Tuple x y) -> Tuple x <$> b pafb y)
25+
26+
instance choiceBazaar :: Choice (Bazaar p a b) where
27+
left (Bazaar b) = Bazaar (\pafb e -> bitraverse (b pafb) pure e)
28+
right (Bazaar b) = Bazaar (\pafb e -> traverse (b pafb) e)
29+
30+
instance wanderBazaar :: Wander (Bazaar p a b) where
31+
wander w (Bazaar f) = Bazaar (\pafb s -> w (f pafb) s)

src/Data/Lens/Traversal.purs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ module Data.Lens.Traversal
2525
, failover
2626
, elementsOf
2727
, itraverseOf
28+
, cloneTraversal
2829
, module ExportTypes
2930
) where
3031

@@ -33,7 +34,8 @@ import Prelude
3334
import Control.Alternative (class Alternative)
3435
import Control.Plus (empty)
3536
import Data.Lens.Indexed (iwander, positions, unIndex)
36-
import Data.Lens.Types (IndexedTraversal, IndexedOptic, Indexed(..), Traversal, Optic, class Wander, wander)
37+
import Data.Lens.Internal.Bazaar (Bazaar(..), runBazaar)
38+
import Data.Lens.Types (ATraversal, IndexedTraversal, IndexedOptic, Indexed(..), Traversal, Optic, class Wander, wander)
3739
import Data.Lens.Types (Traversal, Traversal') as ExportTypes
3840
import Data.Monoid.Disj (Disj(..))
3941
import Data.Newtype (under, unwrap)
@@ -148,3 +150,6 @@ iforOf
148150
-> (i -> a -> f b)
149151
-> f t
150152
iforOf = flip <<< itraverseOf
153+
154+
cloneTraversal :: forall s t a b. ATraversal s t a b -> Traversal s t a b
155+
cloneTraversal l = wander (runBazaar (l (Bazaar identity)))

src/Data/Lens/Types.purs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ module Data.Lens.Types
1313
) where
1414

1515
import Data.Tuple
16+
17+
import Data.Lens.Internal.Bazaar (Bazaar)
1618
import Data.Lens.Internal.Exchange (Exchange(..))
1719
import Data.Lens.Internal.Forget (Forget(..))
1820
import Data.Lens.Internal.Grating (Grating)
@@ -88,8 +90,8 @@ type Iso' s a = Iso s s a a
8890
type Traversal s t a b = forall p. Wander p => Optic p s t a b
8991
type Traversal' s a = Traversal s s a a
9092

91-
92-
93+
type ATraversal s t a b = Optic (Bazaar (->) a b) s t a b
94+
type ATraversal' s a = ATraversal s s a a
9395

9496
-- | A general-purpose Data.Lens.
9597
type Optic p s t a b = p a b -> p s t

test/Main.purs

Lines changed: 13 additions & 2 deletions
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', _1, _2, _Just, _Left, collectOf, lens, takeBoth, traversed, view)
8+
import Data.Lens (Getter', _1, _2, _Just, _Left, collectOf, lens, preview, takeBoth, traversed, view)
99
import Data.Lens.Fold ((^?))
1010
import Data.Lens.Fold.Partial ((^?!), (^@?!))
1111
import Data.Lens.Grate (Grate, cloneGrate, grate, zipWithOf)
@@ -14,7 +14,8 @@ import Data.Lens.Indexed (itraversed, reindexed)
1414
import Data.Lens.Lens (ilens, IndexedLens, cloneIndexedLens)
1515
import Data.Lens.Record (prop)
1616
import Data.Lens.Setter (iover)
17-
import Data.Lens.Zoom (IndexedTraversal', Traversal, Traversal', Lens, Lens', zoom)
17+
import Data.Lens.Traversal (cloneTraversal)
18+
import Data.Lens.Zoom (ATraversal', IndexedTraversal', Traversal, Traversal', Lens, Lens', zoom)
1819
import Data.Maybe (Maybe(..))
1920
import Data.Symbol (SProxy(..))
2021
import Data.Tuple (Tuple(..), fst, snd)
@@ -94,6 +95,15 @@ collectOfTest = collectOf aGrateExample
9495
summing :: Tuple Int Int -> Tuple Int Int -> Tuple Int Int
9596
summing = zipWithOf (cloneGrate aGrateExample) (+)
9697

98+
-- Test cloning of traversals
99+
cloneTraversalTest :: Maybe Int
100+
cloneTraversalTest =
101+
let t :: Traversal' (Array Int) Int
102+
t = ix 1
103+
wrapper :: { traversal :: ATraversal' (Array Int) Int }
104+
wrapper = { traversal: t }
105+
in preview (cloneTraversal wrapper.traversal) [ 0, 1, 2 ]
106+
97107
main :: Effect Unit
98108
main = do
99109
logShow $ view bars doc
@@ -104,3 +114,4 @@ main = do
104114
logShow stateTest
105115
logShow cloneTest
106116
logShow (summing (Tuple 1 2) (Tuple 3 4))
117+
logShow cloneTraversalTest

0 commit comments

Comments
 (0)