@@ -12,12 +12,16 @@ import qualified Data.Bifunctor.Linear as Bifunctor
1212import Data.Bifunctor.Linear (SymmetricMonoidal )
1313import Data.Functor.Const
1414import Data.Functor.Linear
15- import Data.Monoid
15+ import Data.Semigroup.Linear
1616import Data.Profunctor.Linear
1717import Data.Void
18- import Prelude.Linear
18+ import Prelude.Linear hiding ((<$>) )
19+ -- ^ XXX: not entirely sure why the hiding is necessary here...
1920import qualified Prelude as P
2021
22+ -- TODO: documentation in this module
23+ -- Put the functions in some sensible order: possibly split into separate
24+ -- Lens/Prism/Traversal/Iso modules
2125newtype Optic_ arr a b s t = Optical (a `arr ` b -> s `arr ` t )
2226
2327type Optic c a b s t =
@@ -29,8 +33,12 @@ type Lens a b s t = Optic (Strong (,) ()) a b s t
2933type Lens' a s = Lens a a s s
3034type Prism a b s t = Optic (Strong Either Void ) a b s t
3135type Prism' a s = Prism a a s s
32- type Traversal a b s t = Optic Wandering a b s t
33- type Traversal' a s = Traversal a a s s
36+ type PTraversal a b s t = Optic PWandering a b s t
37+ type PTraversal' a s = PTraversal a a s s
38+ type DTraversal a b s t = Optic DWandering a b s t
39+ type DTraversal' a s = DTraversal a a s s
40+ -- XXX: these will unify into
41+ -- type Traversal (p :: Multiplicity) a b s t = Optic (Wandering p) a b s t
3442
3543swap :: SymmetricMonoidal m u => Iso (a `m ` b ) (c `m ` d ) (b `m ` a ) (d `m ` c )
3644swap = iso Bifunctor. swap Bifunctor. swap
@@ -41,6 +49,10 @@ assoc = iso Bifunctor.lassoc Bifunctor.rassoc
4149(.>) :: Optic_ arr a b s t -> Optic_ arr x y a b -> Optic_ arr x y s t
4250Optical f .> Optical g = Optical (f P. . g)
4351
52+ -- c is the complement (probably)
53+ lens :: (s ->. (c ,a )) -> ((c ,b ) ->. t ) -> Lens a b s t
54+ lens sca cbt = Optical $ \ f -> dimap sca cbt (second f)
55+
4456prism :: (b ->. t ) -> (s ->. Either t a ) -> Prism a b s t
4557prism b s = Optical $ \ f -> dimap s (either id id ) (second (rmap b f))
4658
@@ -50,6 +62,37 @@ _1 = Optical first
5062_2 :: Lens a b (c ,a ) (c ,b )
5163_2 = Optical second
5264
65+ -- XXX: these will unify to
66+ -- > both :: forall (p :: Multiplicity). Traversal p a b (a,a) (b,b)
67+ both' :: PTraversal a b (a ,a ) (b ,b )
68+ both' = _Pairing .> ptraversed
69+
70+ both :: DTraversal a b (a ,a ) (b ,b )
71+ both = _Pairing .> dtraversed
72+
73+ -- XXX: these are a special case of Bitraversable, but just the simple case
74+ -- is included here for now
75+ _Pairing :: Iso (Pair a ) (Pair b ) (a ,a ) (b ,b )
76+ _Pairing = iso Paired unpair
77+
78+ newtype Pair a = Paired (a ,a )
79+ unpair :: Pair a ->. (a ,a )
80+ unpair (Paired x) = x
81+
82+ instance P. Functor Pair where
83+ fmap f (Paired (x,y)) = Paired (f x, f y)
84+ instance Functor Pair where
85+ fmap f (Paired (x,y)) = Paired (f x, f y)
86+ instance Foldable Pair where
87+ foldMap f (Paired (x,y)) = f x P. <> f y
88+ instance P. Traversable Pair where
89+ traverse f (Paired (x,y)) = Paired P. <$> ((,) P. <$> f x P. <*> f y)
90+ instance Traversable Pair where
91+ traverse f (Paired (x,y)) = Paired <$> ((,) <$> f x <*> f y)
92+
93+ toListOf :: Optic_ (Kleisli (Const [a ])) a b s t -> s -> [a ]
94+ toListOf l = gets l (\ a -> [a])
95+
5396_Left :: Prism a b (Either a c ) (Either b c )
5497_Left = Optical first
5598
@@ -62,8 +105,11 @@ _Just = prism Just (maybe (Left Nothing) Right)
62105_Nothing :: Prism' () (Maybe a )
63106_Nothing = prism (\ () -> Nothing ) Left
64107
65- traversed :: Traversable t => Traversal a b (t a ) (t b )
66- traversed = Optical wander
108+ ptraversed :: P. Traversable t => PTraversal a b (t a ) (t b )
109+ ptraversed = Optical pwander
110+
111+ dtraversed :: Traversable t => DTraversal a b (t a ) (t b )
112+ dtraversed = Optical dwander
67113
68114over :: Optic_ LinearArrow a b s t -> (a ->. b ) -> s ->. t
69115over (Optical l) f = getLA (l (LA f))
@@ -74,6 +120,18 @@ traverseOf (Optical l) f = runLKleisli (l (LKleisli f))
74120get :: Optic_ (Kleisli (Const a )) a b s t -> s -> a
75121get l = gets l P. id
76122
123+ preview :: Optic_ (Kleisli (Const (Maybe (First a )))) a b s t -> s -> Maybe a
124+ preview (Optical l) s = getFirst P. <$> (getConst (runKleisli (l (Kleisli (\ a -> Const (Just (First a))))) s))
125+
126+ get' :: Optic_ (LKleisli (Const (Top , a ))) a b s t -> s ->. (Top , a )
127+ get' l = gets' l id
128+
129+ gets' :: Optic_ (LKleisli (Const (Top , r ))) a b s t -> (a ->. r ) -> s ->. (Top , r )
130+ gets' (Optical l) f s = getConst' (runLKleisli (l (LKleisli (\ a -> Const (Top () , f a)))) s)
131+
132+ set' :: Optic_ (LKleisli (MyFunctor a b )) a b s t -> s ->. b ->. (a , t )
133+ set' (Optical l) = runMyFunctor . runLKleisli (l (LKleisli (\ a -> MyFunctor (\ b -> (a,b)))))
134+
77135gets :: Optic_ (Kleisli (Const r )) a b s t -> (a -> r ) -> s -> r
78136gets (Optical l) f s = getConst' (runKleisli (l (Kleisli (Const P. . f))) s)
79137
@@ -115,4 +173,3 @@ iso f g = Optical (dimap f g)
115173withIso :: Optic_ (Exchange a b ) a b s t -> ((s ->. a ) -> (b ->. t ) -> r ) -> r
116174withIso (Optical l) f = f fro to
117175 where Exchange fro to = l (Exchange id id )
118-
0 commit comments