Skip to content

Commit c58fde5

Browse files
committed
Merge pull request #19 from zrho/master
Some rudimentary interaction with state monads.
2 parents e6b0fab + abe2ed0 commit c58fde5

File tree

12 files changed

+224
-11
lines changed

12 files changed

+224
-11
lines changed

bower.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"purescript-maps": "~0.5.2",
2323
"purescript-profunctor": "~0.3.0",
2424
"purescript-sets": "~0.5.1",
25-
"purescript-unsafe-coerce": "~0.1.0"
25+
"purescript-unsafe-coerce": "~0.1.0",
26+
"purescript-transformers": "~0.8.1"
2627
}
2728
}

src/Data/Lens/Fold.purs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import Prelude
1212

1313
import Control.Apply ((*>))
1414

15-
import Data.Const (Const(..), getConst)
1615
import Data.Either (Either(..), either)
1716
import Data.Foldable (Foldable, foldr)
1817
import Data.Functor.Contravariant (Contravariant)
@@ -32,6 +31,7 @@ import Data.Profunctor.Star (Star(..), runStar)
3231
import Data.Tuple (Tuple(..))
3332

3433
import Data.Lens.Internal.Void (coerce)
34+
import Data.Lens.Internal.Forget (Forget (..), runForget)
3535
import Data.Lens.Types (Fold(), FoldP()) as ExportTypes
3636
import Data.Lens.Types (Optic(), OpticP(), Fold())
3737

@@ -48,11 +48,11 @@ preview p = runFirst <<< foldMapOf p (First <<< Just)
4848

4949
-- | Folds all foci of a `Fold` to one. Note that this is the same as `view`.
5050
foldOf :: forall s t a b. Fold a s t a b -> s -> a
51-
foldOf p = getConst <<< runStar (p (Star Const))
51+
foldOf p = runForget (p (Forget id))
5252

5353
-- | Maps and then folds all foci of a `Fold`.
5454
foldMapOf :: forall s t a b r. Fold r s t a b -> (a -> r) -> s -> r
55-
foldMapOf p f = getConst <<< runStar (p (Star (Const <<< f)))
55+
foldMapOf p f = runForget (p (Forget f))
5656

5757
-- | Right fold over a `Fold`.
5858
foldrOf :: forall s t a b r. Fold (Endo r) s t a b -> (a -> r -> r) -> r -> s -> r

src/Data/Lens/Getter.purs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,25 @@
22

33
module Data.Lens.Getter
44
( (^.)
5-
, view, to
5+
, view, to, use
66
, module Data.Lens.Types
77
) where
88

9-
import Prelude ((<<<))
9+
import Prelude (id, (<<<))
1010

1111
import Data.Const (Const(..), getConst)
1212
import Data.Functor.Contravariant (Contravariant, cmap)
1313
import Data.Profunctor.Star (Star(..), runStar)
14+
import Control.Monad.State.Class (MonadState, gets)
1415

16+
import Data.Lens.Internal.Forget (Forget (..), runForget)
1517
import Data.Lens.Types (Getter(), Optic())
1618

1719
infixl 8 ^.
1820

1921
-- | View the focus of a `Getter`.
2022
view :: forall s t a b. Getter s t a b -> s -> a
21-
view l s = getConst (runStar (l (Star Const)) s)
23+
view l = runForget (l (Forget id))
2224

2325
-- | Synonym for `view`, flipped.
2426
(^.) :: forall s t a b. s -> Getter s t a b -> a
@@ -27,3 +29,6 @@ view l s = getConst (runStar (l (Star Const)) s)
2729
-- | Convert a function into a getter.
2830
to :: forall s a f. (Contravariant f) => (s -> a) -> Optic (Star f) s s a a
2931
to f p = Star (cmap f <<< runStar p <<< f)
32+
33+
use :: forall s t a b m. (MonadState s m) => Getter s t a b -> m a
34+
use p = gets (^. p)

src/Data/Lens/Internal/Focusing.purs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
-- | This module defines the `Focusing` functor
2+
3+
module Data.Lens.Internal.Focusing
4+
( Focusing (..)
5+
, runFocusing
6+
) where
7+
8+
import Prelude
9+
import Data.Monoid (Monoid)
10+
import Data.Tuple (Tuple ())
11+
12+
-- | The functor used to zoom into `StateT`.
13+
newtype Focusing m s a = Focusing (m (Tuple s a))
14+
15+
runFocusing :: forall m s a. Focusing m s a -> m (Tuple s a)
16+
runFocusing (Focusing r) = r
17+
18+
instance focusingFunctor :: (Functor m) => Functor (Focusing m s) where
19+
map f (Focusing r) = Focusing (map (map f) r)
20+
21+
instance focusingApply :: (Apply m, Semigroup s) => Apply (Focusing m s) where
22+
apply (Focusing rf) (Focusing rx) = Focusing (map (<*>) rf <*> rx)
23+
24+
instance focusingApplicative :: (Applicative m, Monoid s) => Applicative (Focusing m s) where
25+
pure = Focusing <<< pure <<< pure

src/Data/Lens/Internal/Forget.purs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
module Data.Lens.Internal.Forget where
2+
3+
import Prelude
4+
5+
import Data.Tuple (Tuple (..), fst, snd)
6+
import Data.Either (Either (..), either)
7+
import Data.Monoid (Monoid, mempty)
8+
import Data.Const (Const (..), getConst)
9+
import Data.Profunctor (Profunctor)
10+
import Data.Profunctor.Strong (Strong)
11+
import Data.Profunctor.Choice (Choice)
12+
import Data.Profunctor.Cochoice (Cochoice)
13+
14+
import Data.Lens.Internal.Wander (Wander)
15+
16+
-- | Profunctor that forgets the `b` value and returns (and accumulates) a
17+
-- | value of type `r`.
18+
-- |
19+
-- | `Forget r` is isomorphic to `Star (Const r)`, but can be given a `Cochoice`
20+
-- | instance.
21+
newtype Forget r a b = Forget (a -> r)
22+
23+
-- | Unwrap a value of type `Forget`.
24+
runForget :: forall r a b. Forget r a b -> a -> r
25+
runForget (Forget z) = z
26+
27+
instance profunctorForget :: Profunctor (Forget r) where
28+
dimap f _ (Forget z) = Forget (z <<< f)
29+
30+
instance choiceForget :: (Monoid r) => Choice (Forget r) where
31+
left (Forget z) = Forget (either z mempty)
32+
right (Forget z) = Forget (either mempty z)
33+
34+
instance strongForget :: Strong (Forget r) where
35+
first (Forget z) = Forget (z <<< fst)
36+
second (Forget z) = Forget (z <<< snd)
37+
38+
instance cochoiceForget :: Cochoice (Forget r) where
39+
unleft (Forget z) = Forget (z <<< Left)
40+
unright (Forget z) = Forget (z <<< Right)
41+
42+
instance wanderForget :: (Monoid r) => Wander (Forget r) where
43+
wander f (Forget r) = Forget \s -> getConst (f (Const <<< r) s)
44+
45+
-- forall s t a b. (forall f. (Applicative f) => (a -> f b) -> s -> f t)
46+
-- -> p a b -> p s t

src/Data/Lens/Internal/Re.purs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
-- | This module defines the `Re` profunctor
2+
3+
module Data.Lens.Internal.Re where
4+
5+
import Prelude
6+
7+
import Data.Profunctor
8+
import Data.Profunctor.Strong
9+
import Data.Profunctor.Choice
10+
import Data.Profunctor.Cochoice
11+
import Data.Profunctor.Costrong
12+
13+
--
14+
newtype Re p s t a b = Re (p b a -> p t s)
15+
16+
runRe :: forall p s t a b. Re p s t a b -> p b a -> p t s
17+
runRe (Re r) = r
18+
19+
instance profunctorRe :: (Profunctor p) => Profunctor (Re p s t) where
20+
dimap f g (Re r) = Re (r <<< dimap g f)
21+
22+
instance choiceRe :: (Choice p) => Cochoice (Re p s t) where
23+
unleft (Re r) = Re (r <<< left)
24+
unright (Re r) = Re (r <<< right)
25+
26+
instance cochoiceRe :: (Cochoice p) => Choice (Re p s t) where
27+
left (Re r) = Re (r <<< unleft)
28+
right (Re r) = Re (r <<< unright)
29+
30+
instance strongRe :: (Strong p) => Costrong (Re p s t) where
31+
unfirst (Re r) = Re (r <<< first)
32+
unsecond (Re r) = Re (r <<< second)
33+
34+
instance costrongRe :: (Costrong p) => Strong (Re p s t) where
35+
first (Re r) = Re (r <<< unfirst)
36+
second (Re r) = Re (r <<< unsecond)

src/Data/Lens/Internal/Tagged.purs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ module Data.Lens.Internal.Tagged where
44

55
import Data.Profunctor (Profunctor)
66
import Data.Profunctor.Choice (Choice)
7+
import Data.Profunctor.Costrong (Costrong)
78
import Data.Either (Either(..))
9+
import Data.Tuple (Tuple(..))
810

911
newtype Tagged a b = Tagged b
1012

@@ -15,5 +17,9 @@ instance taggedChoice :: Choice Tagged where
1517
left (Tagged x) = Tagged (Left x)
1618
right (Tagged x) = Tagged (Right x)
1719

20+
instance taggedCostrong :: Costrong Tagged where
21+
unfirst (Tagged (Tuple b _)) = Tagged b
22+
unsecond (Tagged (Tuple _ c)) = Tagged c
23+
1824
unTagged :: forall a b. Tagged a b -> b
1925
unTagged (Tagged x) = x

src/Data/Lens/Iso.purs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
-- | This module defines functions for working with isomorphisms.
22

33
module Data.Lens.Iso
4-
( iso, withIso, cloneIso, au, auf, under, curried, uncurried, flipped
4+
( iso, withIso, cloneIso, re, au, auf, under, curried, uncurried, flipped
55
, module Data.Lens.Types
66
) where
77

@@ -10,7 +10,7 @@ import Prelude ((<<<), flip, id)
1010
import Data.Profunctor (Profunctor, dimap, rmap)
1111
import Data.Tuple (Tuple(), curry, uncurry)
1212

13-
import Data.Lens.Types (Iso(), IsoP(), AnIso(), AnIsoP(), Exchange(..))
13+
import Data.Lens.Types (Iso(), IsoP(), AnIso(), AnIsoP(), Optic(), Exchange(..), Re(..), runRe)
1414

1515
-- | Create an `Iso` from a pair of morphisms.
1616
iso :: forall s t a b. (s -> a) -> (b -> t) -> Iso s t a b
@@ -25,6 +25,10 @@ withIso l f = case l (Exchange id id) of
2525
cloneIso :: forall s t a b. AnIso s t a b -> Iso s t a b
2626
cloneIso l = withIso l \x y p -> iso x y p
2727

28+
-- | Reverses an optic.
29+
re :: forall p s t a b. Optic (Re p a b) s t a b -> Optic p b a t s
30+
re t = runRe (t (Re id))
31+
2832
au :: forall s t a b e. AnIso s t a b -> ((b -> t) -> e -> s) -> e -> a
2933
au l = withIso l \sa bt f e -> sa (f bt e)
3034

src/Data/Lens/Setter.purs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22

33
module Data.Lens.Setter
44
( (%~), (.~), (+~), (-~), (*~), (//~), (||~), (&&~), (<>~), (++~), (?~)
5+
, (.=), (%=), (+=), (*=), (-=), (//=), (||=), (&&=), (<>=), (++=), (?=)
56
, over, set
67
, module Data.Lens.Types
78
) where
89

910
import Prelude
1011

12+
import Control.Monad.State.Class (MonadState, modify)
1113
import Data.Maybe (Maybe(..))
1214

1315
import Data.Lens.Types (Setter(), SetterP())
@@ -24,6 +26,18 @@ infixr 4 <>~
2426
infixr 4 ++~
2527
infixr 4 ?~
2628

29+
infix 4 .=
30+
infix 4 %=
31+
infix 4 +=
32+
infix 4 *=
33+
infix 4 -=
34+
infix 4 //=
35+
infix 4 ||=
36+
infix 4 &&=
37+
infix 4 <>=
38+
infix 4 ++=
39+
infix 4 ?=
40+
2741
-- | Apply a function to the foci of a `Setter`.
2842
over :: forall s t a b. Setter s t a b -> (a -> b) -> s -> t
2943
over l = l
@@ -66,3 +80,48 @@ set l b = over l (const b)
6680

6781
(?~) :: forall s t a b. Setter s t a (Maybe b) -> b -> s -> t
6882
(?~) p = set p <<< Just
83+
84+
-- Stateful
85+
86+
-- | Set the foci of a `Setter` in a monadic state to a constant value.
87+
assign :: forall s a b m. (MonadState s m) => Setter s s a b -> b -> m Unit
88+
assign p b = modify (set p b)
89+
90+
-- | Modify the foci of a `Setter` in a monadic state.
91+
modifying :: forall s a b m. (MonadState s m) => Setter s s a b -> (a -> b) -> m Unit
92+
modifying p f = modify (over p f)
93+
94+
-- | Synonym for `assign`
95+
(.=) :: forall s a b m. (MonadState s m) => Setter s s a b -> b -> m Unit
96+
(.=) = assign
97+
98+
-- | Synonym for `modifying`
99+
(%=) :: forall s a b m. (MonadState s m) => Setter s s a b -> (a -> b) -> m Unit
100+
(%=) = modifying
101+
102+
(+=) :: forall s a m. (MonadState s m, Semiring a) => SetterP s a -> a -> m Unit
103+
(+=) p = modifying p <<< add
104+
105+
(*=) :: forall s a m. (MonadState s m, Semiring a) => SetterP s a -> a -> m Unit
106+
(*=) p = modifying p <<< flip mul
107+
108+
(-=) :: forall s a m. (MonadState s m, Ring a) => SetterP s a -> a -> m Unit
109+
(-=) p = modifying p <<< flip sub
110+
111+
(//=) :: forall s a m. (MonadState s m, DivisionRing a) => SetterP s a -> a -> m Unit
112+
(//=) p = modifying p <<< flip div
113+
114+
(||=) :: forall s a m. (MonadState s m, BooleanAlgebra a) => SetterP s a -> a -> m Unit
115+
(||=) p = modifying p <<< flip disj
116+
117+
(&&=) :: forall s a m. (MonadState s m, BooleanAlgebra a) => SetterP s a -> a -> m Unit
118+
(&&=) p = modifying p <<< flip conj
119+
120+
(<>=) :: forall s a m. (MonadState s m, Semigroup a) => SetterP s a -> a -> m Unit
121+
(<>=) p = modifying p <<< flip append
122+
123+
(++=) :: forall s a m. (MonadState s m, Semigroup a) => SetterP s a -> a -> m Unit
124+
(++=) p = modifying p <<< flip append
125+
126+
(?=) :: forall s a b m. (MonadState s m) => Setter s s a (Maybe b) -> b -> m Unit
127+
(?=) p = assign p <<< Just

src/Data/Lens/Types.purs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,25 @@ module Data.Lens.Types
66
, module Data.Lens.Internal.Market
77
, module Data.Lens.Internal.Shop
88
, module Data.Lens.Internal.Tagged
9+
, module Data.Lens.Internal.Forget
910
, module Data.Lens.Internal.Wander
11+
, module Data.Lens.Internal.Re
1012
) where
1113

1214
import Data.Const (Const())
1315
import Data.Profunctor (Profunctor)
1416
import Data.Profunctor.Choice (Choice)
1517
import Data.Profunctor.Star (Star())
1618
import Data.Profunctor.Strong (Strong)
19+
import Data.Profunctor.Closed (Closed)
1720

1821
import Data.Lens.Internal.Exchange (Exchange(..))
1922
import Data.Lens.Internal.Market (Market(..))
2023
import Data.Lens.Internal.Shop (Shop(..))
2124
import Data.Lens.Internal.Tagged (Tagged(..), unTagged)
25+
import Data.Lens.Internal.Forget (Forget(..), runForget)
2226
import Data.Lens.Internal.Wander (Wander, wander)
27+
import Data.Lens.Internal.Re (Re(..), runRe)
2328

2429
-- | A general-purpose Data.Lens.
2530
type Optic p s t a b = p a b -> p s t
@@ -63,5 +68,5 @@ type Review s t a b = Optic Tagged s t a b
6368
type ReviewP s a = Review s s a a
6469

6570
-- | A fold.
66-
type Fold r s t a b = Optic (Star (Const r)) s t a b
71+
type Fold r s t a b = Optic (Forget r) s t a b
6772
type FoldP r s a = Fold r s s a a

0 commit comments

Comments
 (0)