66{-# LANGUAGE RankNTypes #-}
77{-# LANGUAGE TypeOperators #-}
88
9- module Control.Optics.Linear.Internal where
9+ module Control.Optics.Linear.Internal
10+ ( -- * Types
11+ Optic_ (.. )
12+ , Optic
13+ , Iso , Iso'
14+ , Lens , Lens'
15+ , Prism , Prism'
16+ , Traversal , Traversal'
17+ -- * Composing optics
18+ , (.>)
19+ -- * Common optics
20+ , swap , assoc
21+ , _1 , _2
22+ , _Left , _Right
23+ , _Just , _Nothing
24+ , traversed
25+ -- * Using optics
26+ , get , set , gets
27+ , match , match' , build
28+ , over , over'
29+ , traverseOf , traverseOf'
30+ , lengthOf
31+ , withIso
32+ -- * Constructing optics
33+ , iso , prism
34+ )
35+ where
1036
1137import qualified Data.Bifunctor.Linear as Bifunctor
1238import Data.Bifunctor.Linear (SymmetricMonoidal )
1339import Data.Functor.Const
1440import Data.Functor.Linear
1541import Data.Monoid
1642import Data.Profunctor.Linear
43+ import qualified Data.Profunctor.Kleisli.Linear as Linear
44+ import qualified Data.Profunctor.Kleisli.NonLinear as NonLinear
1745import Data.Void
1846import Prelude.Linear
1947import qualified Prelude as P
@@ -33,14 +61,17 @@ type Traversal a b s t = Optic Wandering a b s t
3361type Traversal' a s = Traversal a a s s
3462
3563swap :: SymmetricMonoidal m u => Iso (a `m ` b ) (c `m ` d ) (b `m ` a ) (d `m ` c )
36- swap = Optical (dimap Bifunctor. swap Bifunctor. swap)
64+ swap = iso Bifunctor. swap Bifunctor. swap
3765
3866assoc :: SymmetricMonoidal m u => Iso ((a `m ` b ) `m ` c ) ((d `m ` e ) `m ` f ) (a `m ` (b `m ` c )) (d `m ` (e `m ` f ))
39- assoc = Optical (dimap Bifunctor. lassoc Bifunctor. rassoc)
67+ assoc = iso Bifunctor. lassoc Bifunctor. rassoc
4068
4169(.>) :: Optic_ arr a b s t -> Optic_ arr x y a b -> Optic_ arr x y s t
4270Optical f .> Optical g = Optical (f P. . g)
4371
72+ prism :: (b ->. t ) -> (s ->. Either t a ) -> Prism a b s t
73+ prism b s = Optical $ \ f -> dimap s (either id id ) (second (rmap b f))
74+
4475_1 :: Lens a b (a ,c ) (b ,c )
4576_1 = Optical first
4677
@@ -53,31 +84,60 @@ _Left = Optical first
5384_Right :: Prism a b (Either c a ) (Either c b )
5485_Right = Optical second
5586
87+ _Just :: Prism a b (Maybe a ) (Maybe b )
88+ _Just = prism Just (maybe (Left Nothing ) Right )
89+
90+ _Nothing :: Prism' () (Maybe a )
91+ _Nothing = prism (\ () -> Nothing ) Left
92+
5693traversed :: Traversable t => Traversal a b (t a ) (t b )
5794traversed = Optical wander
5895
5996over :: Optic_ LinearArrow a b s t -> (a ->. b ) -> s ->. t
6097over (Optical l) f = getLA (l (LA f))
6198
62- traverseOf :: Optic_ (LKleisli f ) a b s t -> (a ->. f b ) -> s ->. f t
63- traverseOf (Optical l) f = runLKleisli (l (LKleisli f))
99+ traverseOf :: Optic_ (Linear. Kleisli f ) a b s t -> (a ->. f b ) -> s ->. f t
100+ traverseOf (Optical l) f = Linear. runKleisli (l (Linear. Kleisli f))
64101
65- get :: Optic_ (Kleisli (Const a )) a b s t -> s -> a
102+ get :: Optic_ (NonLinear. Kleisli (Const a )) a b s t -> s -> a
66103get l = gets l P. id
67104
68- gets :: Optic_ (Kleisli (Const r )) a b s t -> (a -> r ) -> s -> r
69- gets (Optical l) f s = getConst ( runKleisli (l (Kleisli (Const P. . f))) s)
105+ gets :: Optic_ (NonLinear. Kleisli (Const r )) a b s t -> (a -> r ) -> s -> r
106+ gets (Optical l) f s = getConst' ( NonLinear. runKleisli (l (NonLinear. Kleisli (Const P. . f))) s)
70107
71108set :: Optic_ (-> ) a b s t -> b -> s -> t
72109set (Optical l) x = l (const x)
73110
74- lengthOf :: Num r => Optic_ (Kleisli (Const (Sum r ))) a b s t -> s -> r
111+ match :: Optic_ (Linear. Kleisli (Either a )) a b s t -> s ->. Either t a
112+ match (Optical l) = withIso swap (\ x _ -> x) . Linear. runKleisli (l (Linear. Kleisli Left ))
113+
114+ -- will be redundant with multiplicity polymorphism
115+ match' :: Optic_ (NonLinear. Kleisli (Either a )) a b s t -> s -> Either t a
116+ match' (Optical l) = withIso swap (\ x _ -> forget x) P. . NonLinear. runKleisli (l (NonLinear. Kleisli Left ))
117+
118+ build :: Optic_ (Linear. CoKleisli (Const b )) a b s t -> b ->. t
119+ build (Optical l) x = Linear. runCoKleisli (l (Linear. CoKleisli getConst')) (Const x)
120+
121+ -- XXX: move this to Prelude
122+ -- | Linearly typed patch for the newtype deconstructor. (Temporary until
123+ -- inference will get this from the newtype declaration.)
124+ getConst' :: Const a b ->. a
125+ getConst' (Const x) = x
126+
127+ lengthOf :: Num r => Optic_ (NonLinear. Kleisli (Const (Sum r ))) a b s t -> s -> r
75128lengthOf l s = getSum (gets l (const (Sum 1 )) s)
76129
77130-- XXX: the below two functions will be made redundant with multiplicity
78131-- polymorphism on over and traverseOf'
79132over' :: Optic_ (-> ) a b s t -> (a -> b ) -> s -> t
80133over' (Optical l) f = l f
81134
82- traverseOf' :: Optic_ (Kleisli f ) a b s t -> (a -> f b ) -> s -> f t
83- traverseOf' (Optical l) f = runKleisli (l (Kleisli f))
135+ traverseOf' :: Optic_ (NonLinear. Kleisli f ) a b s t -> (a -> f b ) -> s -> f t
136+ traverseOf' (Optical l) f = NonLinear. runKleisli (l (NonLinear. Kleisli f))
137+
138+ iso :: (s ->. a ) -> (b ->. t ) -> Iso a b s t
139+ iso f g = Optical (dimap f g)
140+
141+ withIso :: Optic_ (Exchange a b ) a b s t -> ((s ->. a ) -> (b ->. t ) -> r ) -> r
142+ withIso (Optical l) f = f fro to
143+ where Exchange fro to = l (Exchange id id )
0 commit comments