@@ -9,6 +9,21 @@ module Control.SemiIso
99 AlternativeMonad,
1010 maskr,
1111 maskl,
12+ isoCheck,
13+ siCheck,
14+ check,
15+ konst,
16+ isoConst,
17+ assoc,
18+ ($$$),
19+ (*>>),
20+ (**>),
21+ (>>*),
22+ (>**),
23+ (<<*),
24+ (<**),
25+ (*<<),
26+ (**<),
1227 )
1328where
1429
@@ -90,3 +105,59 @@ maskr (SemiIso e p) = SemiIso (\a -> e a <|> pure ()) p
90105
91106maskl :: SemiIso () b -> SemiIso () b
92107maskl (SemiIso e p) = SemiIso e (\b -> p b <|> pure ())
108+
109+infixl 1 *>>, **>, >>*, >**, <<*, <**, *<<, **<
110+
111+infixl 3 $$$
112+
113+($$$) :: (PolyArrow m SemiIso, Eq b) => m a b -> m c b -> m (a, c) b
114+a $$$ c = a *** c >>^ check (uncurry (==)) >>^ siPure fst (\x -> (x, x))
115+
116+(*>>) :: (PolyArrow m SemiIso) => m a () -> m a b -> m a b
117+a *>> b = a &&& b >>^ siPure snd ((),)
118+
119+(**>) :: (PolyArrow m SemiIso) => m () () -> m a b -> m a b
120+a **> b = siPure ((),) snd ^>> a *** b >>^ siPure snd ((),)
121+
122+(>>*) :: (PolyArrow m SemiIso, Eq b) => m a b -> m () b -> m a b
123+a >>* b = siPure (,()) fst ^>> a $$$ b
124+
125+(>**) :: (PolyArrow m SemiIso) => m a b -> m () () -> m a b
126+a >** b = siPure (,()) fst ^>> a *** b >>^ siPure fst (,())
127+
128+(<<*) :: (PolyArrow m SemiIso, Eq b) => m a b -> m () b -> m a b
129+a <<* b = siPure ((),) snd ^>> b $$$ a
130+
131+(<**) :: (PolyArrow m SemiIso) => m a b -> m () () -> m a b
132+a <** b = siPure ((),) snd ^>> b *** a >>^ siPure snd ((),)
133+
134+(*<<) :: (PolyArrow m SemiIso) => m a () -> m a b -> m a b
135+a *<< b = b &&& a >>^ siPure fst (,())
136+
137+(**<) :: (PolyArrow m SemiIso) => m () () -> m a b -> m a b
138+a **< b = siPure (,()) fst ^>> b *** a >>^ siPure fst (,())
139+
140+check :: (s -> Bool) -> SemiIso s s
141+check f = isoCheck f id id
142+
143+siCheck ::
144+ (s -> Bool) ->
145+ (forall f. AlternativeMonad f => s -> f a) ->
146+ (forall f. AlternativeMonad f => a -> f s) ->
147+ SemiIso s a
148+siCheck f a b =
149+ SI
150+ (\c -> guard (f c) >> a c)
151+ (b >=> (\c -> guard (f c) >> pure c))
152+
153+isoCheck :: (s -> Bool) -> (s -> a) -> (a -> s) -> SemiIso s a
154+isoCheck f a b = siCheck f (pure . a) (pure . b)
155+
156+isoConst :: s -> a -> SemiIso s a
157+isoConst s a = SI (const $ pure a) (const $ pure s)
158+
159+konst :: Eq x => x -> SemiIso () x
160+konst x = isoConst () x >>> check (== x)
161+
162+assoc :: SemiIso (a, (b, c)) ((a, b), c)
163+assoc = siPure (\(a, (b, c)) -> ((a, b), c)) (\((a, b), c) -> (a, (b, c)))