3 | import Monocle.Optional
4 | import Monocle.Setter
5 | import Monocle.Traversal
6 | import Data.List.Quantifiers.Extra
34 | record Prism s t a b where
36 | getOrModify : s -> Either t a
42 | 0 Prism' : (s,a : Type) -> Type
43 | Prism' s a = Prism s s a a
47 | prism : (a -> Maybe b) -> (b -> a) -> Prism' a b
48 | prism f = P (\v => maybe (Left v) Right (f v))
52 | mapA : Applicative f => Prism s t a b -> (a -> f b) -> s -> f t
53 | mapA (P g r) f v = either pure (map r . f) (g v)
61 | interface ToPrism (0 o : Type -> Type -> Type -> Type -> Type) where
62 | toPrism : o s t a b -> Prism s t a b
64 | public export %inline
65 | ToPrism Prism where toPrism = id
72 | ToOptional Prism where
73 | toOptional (P g r) = O g (\f => either id (r . f) . g)
76 | ToSetter Prism where
77 | toSetter (P g r) = S $
\f,vs => either id (r . f) (g vs)
81 | toFold (P g r) = F $
\f => either (const neutral) f . g
84 | ToTraversal Prism where
85 | toTraversal o = T (mapA o) (toFold o) (toSetter o)
93 | (~>) : Prism s t a b -> Prism a b c d -> Prism s t c d
94 | P g1 r1 ~> P g2 r2 =
95 | P (\v => g1 v >>= mapFst r1 . g2)
104 | left' : Prism (Either a b) (Either c b) a c
105 | left' = P (either Right (Left . Right)) Left
111 | public export %inline
112 | left : Prism' (Either a b) a
117 | right' : Prism (Either a b) (Either a c) b c
118 | right' = P (either (Left . Left) Right) Right
124 | public export %inline
125 | right : Prism' (Either a b) b
130 | just' : Prism (Maybe a) (Maybe b) a b
131 | just' = P (maybe (Left Nothing) Right) Just
137 | public export %inline
138 | just : Prism' (Maybe a) a
143 | nothing : Prism' (Maybe a) ()
144 | nothing = P (maybe (Right ()) (Left . Just)) (const Nothing)
149 | cons' : Prism (List a) (List b) (a,List a) (b,List b)
150 | cons' = P (\case Nil => Left Nil;
h::t => Right (h,t)) (uncurry (::))
155 | nil : Prism' (List a) ()
156 | nil = prism (\case Nil => Just ();
_ => Nothing) (const Nil)
162 | public export %inline
163 | cons : Prism' (List a) (a,List a)
169 | snoc' : Prism (SnocList a) (SnocList b) (SnocList a,a) (SnocList b,b)
170 | snoc' = P (\case Lin => Left Lin;
i :< l => Right (i,l)) (uncurry (:<))
175 | lin : Prism' (SnocList a) ()
176 | lin = prism (\case Lin => Just ();
_ => Nothing) (const Lin)
182 | public export %inline
183 | snoc : Prism' (SnocList a) (SnocList a,a)
188 | list1' : Prism (List a) (List b) (List1 a) (List1 b)
189 | list1' = P (\case Nil => Left Nil;
h::t => Right (h ::: t)) forget
191 | public export %inline
192 | list1 : Prism' (List a) (List1 a)
199 | -> {0 f : k -> Type}
201 | -> {auto e : Elem t ks}
202 | -> Prism' (Any f ks) (f t)
203 | sum t = prism project' inject
206 | anyHead : Prism' (Any f (k::ks)) (f k)
207 | anyHead = prism (\case Here v => Just v;
_ => Nothing) Here
210 | anyTail : Prism' (Any f (k::ks)) (Any f ks)
211 | anyTail = prism (\case There v => Just v;
_ => Nothing) There
215 | nat : Prism' Integer Nat
216 | nat = prism (\x => toMaybe (x >= 0) (cast x)) cast