0 | module Monocle.Optional
2 | import Control.Monad.State
5 | import Monocle.Setter
6 | import Monocle.Traversal
25 | record Optional s t a b where
27 | getOrModify : s -> Either t a
28 | replace : (a -> b) -> s -> t
33 | 0 Optional' : (s,a : Type) -> Type
34 | Optional' s a = Optional s s a a
38 | optional : (s -> Maybe a) -> ((a -> a) -> s -> s) -> Optional' s a
39 | optional f g = O (\v => maybe (Left v) Right (f v)) g
43 | mapA : Applicative f => Optional s t a b -> (a -> f b) -> s -> f t
47 | Right x => map (\vb => r (const vb) v) (f x)
55 | interface ToOptional (0 o : Type -> Type -> Type -> Type -> Type) where
56 | toOptional : o s t a b -> Optional s t a b
58 | public export %inline
59 | ToOptional Optional where toOptional = id
65 | public export %inline
66 | ToSetter Optional where
67 | toSetter (O g r) = S r
70 | ToFold Optional where
71 | toFold (O g r) = F $
\f => either (const neutral) f . g
74 | ToTraversal Optional where
75 | toTraversal o = T (mapA o) (toFold o) (toSetter o)
83 | (~>) : Optional s t a b -> Optional a b c d -> Optional s t c d
84 | O g1 r1 ~> O g2 r2 =
85 | O (\v => g1 v >>= mapFst (\vb => r1 (const vb) v) . g2)
94 | emptyO : Optional' s a
95 | emptyO = O Left (const id)
99 | getIx : Nat -> List a -> Maybe a
100 | getIx 0 (h::_) = Just h
101 | getIx (S k) (_::t) = getIx k t
102 | getIx _ Nil = Nothing
108 | modIx : Nat -> (a -> a) -> List a -> List a
109 | modIx 0 f (h::xs) = f h :: xs
110 | modIx (S k) f (h::xs) = h :: modIx k f xs
115 | ix : Nat -> Optional' (List a) a
116 | ix n = optional (getIx n) (modIx n)
121 | select : (a -> Bool) -> Optional' a a
124 | (\v => if p v then Just v else Nothing)
125 | (\f,o => if p o then f o else o)
129 | public export %inline
130 | eqBy : Eq b => (v : b) -> (a -> b) -> Optional' a a
131 | eqBy v f = select ((v ==) . f)
134 | modWhere : SnocList a -> (a -> Bool) -> (a -> a) -> List a -> List a
135 | modWhere sa f g [] = sa <>> []
136 | modWhere sa f g (x :: xs) =
137 | if f x then sa <>> (g x :: xs) else modWhere (sa :< x) f g xs
141 | public export %inline
142 | first : (a -> Bool) -> Optional' (List a) a
143 | first f = optional (find f) (modWhere [<] f)
147 | public export %inline
148 | eqFirst : Eq b => b -> (a -> b) -> Optional' (List a) a
149 | eqFirst v f = first ((v ==) . f)
158 | stO : Applicative m => Monoid x => Optional' t s -> StateT s m x -> StateT t m x
160 | ST $
\v => case first o v of
161 | Nothing => pure (v, neutral)
162 | Just vs => (\(vs2,w) => (set o vs2 v, w)) <$> f vs