Skip to content

Commit 7b3056a

Browse files
aspiwackutdemir
authored andcommitted
Add lens and withLens combinators
Translation between the profunctor definition of lens and the more straightforward getter/setter pair. Ported from #79.
1 parent 96377a0 commit 7b3056a

File tree

1 file changed

+15
-5
lines changed

1 file changed

+15
-5
lines changed

src/Control/Optics/Linear/Internal.hs

+15-5
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ module Control.Optics.Linear.Internal
2828
, over, over'
2929
, traverseOf, traverseOf'
3030
, toListOf, lengthOf
31-
, withIso, withPrism
31+
, withIso, withLens, withPrism
3232
-- * Constructing optics
33-
, iso, prism
33+
, iso, lens, prism
3434
)
3535
where
3636

@@ -42,6 +42,8 @@ import Data.Functor.Compose hiding (getCompose)
4242
import Data.Functor.Linear
4343
import qualified Data.Profunctor.Kleisli.Linear as Linear
4444
import Data.Void
45+
import GHC.Exts (FUN)
46+
import GHC.Types
4547
import Prelude.Linear
4648
import qualified Prelude as P
4749

@@ -68,6 +70,10 @@ assoc = iso Bifunctor.lassoc Bifunctor.rassoc
6870
(.>) :: Optic_ arr a b s t -> Optic_ arr x y a b -> Optic_ arr x y s t
6971
Optical f .> Optical g = Optical (f P.. g)
7072

73+
74+
lens :: (s #-> (a, b #-> t)) -> Lens a b s t
75+
lens k = Optical $ \f -> dimap k (\(x,g) -> g $ x) (first f)
76+
7177
prism :: (b #-> t) -> (s #-> Either t a) -> Prism a b s t
7278
prism b s = Optical $ \f -> dimap s (either id id) (second (rmap b f))
7379

@@ -112,9 +118,6 @@ set (Optical l) x = l (const x)
112118

113119
setSwap :: Optic_ (Linear.Kleisli (Compose (LinearArrow b) ((,) a))) a b s t -> s #-> b #-> (a, t)
114120
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
118121

119122
match :: Optic_ (Market a b) a b s t -> s #-> Either t a
120123
match (Optical l) = snd (runMarket (l (Market id Right)))
@@ -149,3 +152,10 @@ withIso (Optical l) f = f fro to
149152
withPrism :: Optic_ (Market a b) a b s t -> ((b #-> t) -> (s #-> Either t a) -> r) -> r
150153
withPrism (Optical l) f = f b m
151154
where Market b m = l (Market id Right)
155+
156+
withLens :: Optic_ (Linear.Kleisli (Compose ((,) a) (FUN 'One b))) a b s t -> s #-> (a, b #-> t)
157+
withLens (Optical l) s = getCompose (Linear.runKleisli (l (Linear.Kleisli (\a -> Compose (a, id)))) s)
158+
159+
-- linear variant of getCompose
160+
getCompose :: Compose f g a #-> f (g a)
161+
getCompose (Compose x) = x

0 commit comments

Comments
 (0)