Skip to content

Commit c729d9d

Browse files
aspiwackutdemir
authored andcommitted
Add setSwap combinator
With a linear lens, we cannot linearly set the value at the lens site in general, however, we can swap the value at the lens site for another, which we get out of the operation. Ported from #79.
1 parent 8b3c19e commit c729d9d

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

src/Control/Optics/Linear/Internal.hs

+12-2
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ module Control.Optics.Linear.Internal
2323
, _Just, _Nothing
2424
, traversed
2525
-- * Using optics
26-
, get, set, gets
26+
, get, set, gets, setSwap
2727
, match, build
2828
, over, over'
2929
, traverseOf, traverseOf'
30-
, lengthOf
30+
, toListOf, lengthOf
3131
, withIso, withPrism
3232
-- * Constructing optics
3333
, iso, prism
@@ -38,6 +38,7 @@ import qualified Control.Arrow as NonLinear
3838
import qualified Data.Bifunctor.Linear as Bifunctor
3939
import Data.Bifunctor.Linear (SymmetricMonoidal)
4040
import Data.Profunctor.Linear
41+
import Data.Functor.Compose hiding (getCompose)
4142
import Data.Functor.Linear
4243
import qualified Data.Profunctor.Kleisli.Linear as Linear
4344
import Data.Void
@@ -97,6 +98,9 @@ over (Optical l) f = getLA (l (LA f))
9798
traverseOf :: Optic_ (Linear.Kleisli f) a b s t -> (a #-> f b) -> s #-> f t
9899
traverseOf (Optical l) f = Linear.runKleisli (l (Linear.Kleisli f))
99100

101+
toListOf :: Optic_ (NonLinear.Kleisli (Const [a])) a b s t -> s -> [a]
102+
toListOf l = gets l (\a -> [a])
103+
100104
get :: Optic_ (NonLinear.Kleisli (Const a)) a b s t -> s -> a
101105
get l = gets l P.id
102106

@@ -106,6 +110,12 @@ gets (Optical l) f s = getConst' (NonLinear.runKleisli (l (NonLinear.Kleisli (Co
106110
set :: Optic_ (->) a b s t -> b -> s -> t
107111
set (Optical l) x = l (const x)
108112

113+
setSwap :: Optic_ (Linear.Kleisli (Compose (LinearArrow b) ((,) a))) a b s t -> s #-> b #-> (a, t)
114+
setSwap (Optical l) s = getLA (getCompose (Linear.runKleisli (l (Linear.Kleisli (\a -> Compose (LA (\b -> (a,b)))))) s))
115+
where
116+
getCompose :: Compose f g a #-> f (g a)
117+
getCompose (Compose x) = x
118+
109119
match :: Optic_ (Market a b) a b s t -> s #-> Either t a
110120
match (Optical l) = snd (runMarket (l (Market id Right)))
111121

src/Data/Functor/Linear/Internal.hs

+9
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ module Data.Functor.Linear.Internal where
55

66
import Prelude.Linear.Internal
77
import Prelude (Maybe(..), Either(..))
8+
import Data.Functor.Compose
89
import Data.Functor.Const
910
import Data.Monoid.Linear
1011
import Data.Functor.Identity
@@ -97,6 +98,14 @@ instance Applicative Identity where
9798
pure = Identity
9899
Identity f <*> Identity x = Identity (f x)
99100

101+
instance (Functor f, Functor g) => Functor (Compose f g) where
102+
fmap f (Compose x) = Compose (fmap (fmap f) x)
103+
104+
instance (Applicative f, Applicative g) => Applicative (Compose f g) where
105+
pure x = Compose (pure (pure x))
106+
(Compose f) <*> (Compose x) = Compose (liftA2 (<*>) f x)
107+
liftA2 f (Compose x) (Compose y) = Compose (liftA2 (liftA2 f) x y)
108+
100109
---------------------------------
101110
-- Monad transformer instances --
102111
---------------------------------

0 commit comments

Comments
 (0)