0 | module Control.Lens.Indexed
3 | import Data.Profunctor
4 | import Data.Profunctor.Costrong
5 | import Data.Profunctor.Traversing
6 | import Data.Profunctor.Mapping
7 | import Data.Bicontravariant
8 | import Control.Lens.Optic
9 | import Control.Lens.Iso
15 | interface Indexable i (0 p, p' : Type -> Type -> Type) | p, p' where
16 | indexed : p' a b -> p (i, a) b
21 | IsIso p => Indexable i p p where
22 | indexed @{MkIsIso _} = lmap snd
26 | [Idxed] Indexable i p (p . (i,)) where
31 | 0 IndexedOptic' : (Type -> Type -> Type) -> (i,s,t,a,b : Type) -> Type
32 | IndexedOptic' p i s t a b = forall p'. Indexable i p p' => p' a b -> p s t
35 | 0 IndexedOptic : ((Type -> Type -> Type) -> Type) -> (i,s,t,a,b : Type) -> Type
36 | IndexedOptic constr i s t a b =
37 | forall p,p'. constr p => Indexable i p p' => p' a b -> p s t
42 | record Indexed i (p : Type -> Type -> Type) a b where
43 | constructor MkIndexed
44 | runIndexed : p (i, a) b
47 | Bifunctor p => Bifunctor (Indexed i p) where
48 | bimap f g (MkIndexed k) = MkIndexed $
bimap (mapSnd f) g k
49 | mapFst f (MkIndexed k) = MkIndexed $
mapFst (mapSnd f) k
50 | mapSnd f (MkIndexed k) = MkIndexed $
mapSnd f k
53 | Bicontravariant p => Bicontravariant (Indexed i p) where
54 | contrabimap f g (MkIndexed k) = MkIndexed $
contrabimap (mapSnd f) g k
57 | Profunctor p => Profunctor (Indexed i p) where
58 | dimap f g (MkIndexed k) = MkIndexed $
dimap (mapSnd f) g k
59 | lmap f (MkIndexed k) = MkIndexed $
lmap (mapSnd f) k
60 | rmap f (MkIndexed k) = MkIndexed $
rmap f k
63 | Bifunctor ten => GenStrong ten p => GenStrong ten (Indexed i p) where
64 | strongl (MkIndexed k) = MkIndexed $
lmap (\(i,x) => mapFst (i,) x) (strongl {ten,p} k)
65 | strongr (MkIndexed k) = MkIndexed $
lmap (\(i,x) => mapSnd (i,) x) (strongr {ten,p} k)
68 | Traversing p => Traversing (Indexed i p) where
69 | wander tr (MkIndexed k) = MkIndexed $
wander (\f,(i,x) => tr (f . (i,)) x) k
72 | Closed p => Closed (Indexed i p) where
73 | closed (MkIndexed k) = MkIndexed $
lmap (\(i,f),x => (i, f x)) (closed k)
76 | Mapping p => Mapping (Indexed i p) where
77 | roam mp (MkIndexed k) = MkIndexed $
roam (\f,(i,x) => mp (f . (i,)) x) k
80 | indexedIso : IsIso p => IsIso (Indexed i p)
81 | indexedIso @{MkIsIso _} = MkIsIso %search
88 | icompose : IsIso p => (i -> j -> k) ->
89 | IndexedOptic' p i s t a b -> IndexedOptic' (Indexed i p) j a b a' b' ->
90 | IndexedOptic' p k s t a' b'
91 | icompose @{MkIsIso _} f l l' @{ind} =
92 | l @{Idxed} . runIndexed . l' @{Idxed} . MkIndexed {p}
93 | . lmap (mapFst (uncurry f) . assocl) . indexed @{ind}
95 | export infixr 9 <.>
, .>
, <.
102 | (<.>) : IsIso p => IndexedOptic' p i s t a b -> IndexedOptic' (Indexed i p) j a b a' b' ->
103 | IndexedOptic' p (i, j) s t a' b'
104 | (<.>) = icompose (,)
110 | (.>) : Optic' p s t a b -> IndexedOptic' p i a b a' b' -> IndexedOptic' p i s t a' b'
117 | (<.) : IndexedOptic' p i s t a b -> Optic' (Indexed i p) a b a' b' -> IndexedOptic' p i s t a' b'
118 | (<.) l l' @{ind} = l @{Idxed} . runIndexed . l' . MkIndexed {p} . indexed @{ind}
123 | constIndex : IsIso p => i -> Optic' p s t a b -> IndexedOptic' p i s t a b
124 | constIndex i l @{MkIsIso _} @{ind} = l . lmap (i,) . indexed @{ind}
128 | reindexed : IsIso p => (i -> j) -> IndexedOptic' p i s t a b -> IndexedOptic' p j s t a b
129 | reindexed @{MkIsIso _} f l @{ind} = l @{Idxed} . lmap (mapFst f) . indexed @{ind}