@@ -28,12 +28,19 @@ module Control.SemiIso
2828 (*<<),
2929 (&<<),
3030 (**<),
31+ siFst,
32+ siSnd,
33+ siDouble,
34+ siSwap,
35+ siTranspose2,
36+ siSequenceEither,
3137 )
3238where
3339
3440import Control.Applicative as X
3541import Control.Arrow.Extra
3642import Control.Monad as X
43+import qualified Data.Bifunctor as Bi
3744import Data.Bitraversable
3845import Data.Tuple
3946import Prelude hiding ((.), id)
@@ -115,44 +122,44 @@ infixl 1 *>>, **>, >>*, >**, <<*, <**, *<<, **<
115122
116123infixl 3 $$$
117124
118−($$$) :: (PolyArrow m SemiIso, Eq b) => m a b -> m c b -> m (a, c) b
119−a $$$ c = a *** c >>^ check (uncurry (==)) >>^ siPure fst (\x -> (x, x))
125+($$$) :: (PolyArrow SemiIso m, Eq b) => m a b -> m c b -> m (a, c) b
126+a $$$ c = a *** c >>^ turn siDouble
120127
121−(*>>) :: (PolyArrow m SemiIso) => m a () -> m a b -> m a b
122−a *>> b = a &&& b >>^ siPure snd ((),)
128+(*>>) :: (PolyArrow SemiIso m) => m a () -> m a b -> m a b
129+a *>> b = a &&& b >>^ siSnd
123130
124−(&>>) :: (PolyArrow m SemiIso) => m a () -> m b c -> m (a, b) c
125−a &>> b = a *** b >>^ siPure snd ((),)
131+(&>>) :: (PolyArrow SemiIso m) => m a () -> m b c -> m (a, b) c
132+a &>> b = a *** b >>^ siSnd
126133
127−(**>) :: (PolyArrow m SemiIso) => m () () -> m a b -> m a b
128−a **> b = siPure ((),) snd ^>> a *** b >>^ siPure snd ((),)
134+(**>) :: (PolyArrow SemiIso m) => m () () -> m a b -> m a b
135+a **> b = turn siSnd ^>> a *** b >>^ siSnd
129136
130−(>>*) :: (PolyArrow m SemiIso, Eq b) => m a b -> m () b -> m a b
131−a >>* b = siPure (,()) fst ^>> a $$$ b
137+(>>*) :: (PolyArrow SemiIso m, Eq b) => m a b -> m () b -> m a b
138+a >>* b = turn siFst ^>> a $$$ b
132139
133−(>>&) :: (PolyArrow m SemiIso) => m a b -> m () c -> m a (b, c)
134−a >>& b = siPure (,()) fst ^>> a *** b >>> undefined
140+(>>&) :: (PolyArrow SemiIso m) => m a b -> m () c -> m a (b, c)
141+a >>& b = turn siFst ^>> a *** b
135142
136−(>**) :: (PolyArrow m SemiIso) => m a b -> m () () -> m a b
137−a >** b = siPure (,()) fst ^>> a *** b >>^ siPure fst (,())
143+(>**) :: (PolyArrow SemiIso m) => m a b -> m () () -> m a b
144+a >** b = turn siFst ^>> a *** b >>^ siFst
138145
139−(<<*) :: (PolyArrow m SemiIso, Eq b) => m a b -> m () b -> m a b
140−a <<* b = siPure ((),) snd ^>> b $$$ a
146+(<<*) :: (PolyArrow SemiIso m, Eq b) => m a b -> m () b -> m a b
147+a <<* b = turn siSnd ^>> b $$$ a
141148
142−(<<&) :: (PolyArrow m SemiIso) => m a b -> m () c -> m a (b, c)
143−a <<& b = siPure ((),) snd ^>> b *** a >>^ siPure swap swap
149+(<<&) :: (PolyArrow SemiIso m) => m a b -> m () c -> m a (b, c)
150+a <<& b = turn siSnd ^>> b *** a >>^ siSwap
144151
145−(<**) :: (PolyArrow m SemiIso) => m a b -> m () () -> m a b
146−a <** b = siPure ((),) snd ^>> b *** a >>^ siPure snd ((),)
152+(<**) :: (PolyArrow SemiIso m) => m a b -> m () () -> m a b
153+a <** b = turn siSnd ^>> b *** a >>^ siSnd
147154
148−(*<<) :: (PolyArrow m SemiIso) => m a () -> m a b -> m a b
149−a *<< b = b &&& a >>^ siPure fst (,())
155+(*<<) :: (PolyArrow SemiIso m) => m a () -> m a b -> m a b
156+a *<< b = b &&& a >>^ siFst
150157
151−(&<<) :: (PolyArrow m SemiIso) => m a () -> m b c -> m (a, b) c
152−a &<< b = siPure swap swap ^>> b *** a >>^ siPure fst (,())
158+(&<<) :: (PolyArrow SemiIso m) => m a () -> m b c -> m (a, b) c
159+a &<< b = siSwap ^>> b *** a >>^ siFst
153160
154−(**<) :: (PolyArrow m SemiIso) => m () () -> m a b -> m a b
155−a **< b = siPure (,()) fst ^>> b *** a >>^ siPure fst (,())
161+(**<) :: (PolyArrow SemiIso m) => m () () -> m a b -> m a b
162+a **< b = turn siFst ^>> b *** a >>^ siFst
156163
157164check :: (s -> Bool) -> SemiIso s s
158165check f = isoCheck f id id
@@ -178,3 +185,22 @@ konst x = isoConst () x >>> check (== x)
178185
179186assoc :: SemiIso (a, (b, c)) ((a, b), c)
180187assoc = siPure (\(a, (b, c)) -> ((a, b), c)) (\((a, b), c) -> (a, (b, c)))
188+
189+siFst :: SemiIso (a, ()) a
190+siFst = siPure fst (,())
191+
192+siSnd :: SemiIso ((), a) a
193+siSnd = siPure snd ((),)
194+
195+siDouble :: (Eq a) => SemiIso a (a, a)
196+siDouble = siPure (\x -> (x, x)) fst >>> check (uncurry (==))
197+
198+siSwap :: SemiIso (a, b) (b, a)
199+siSwap = siPure swap swap
200+
201+siTranspose2 :: SemiIso ((a, b), (c, d)) ((a, c), (b, d))
202+siTranspose2 =
203+ siPure (\((r1, b), (r2, c)) -> ((r1, r2), (b, c))) (\((r1, r2), (b, c)) -> ((r1, b), (r2, c)))
204+
205+siSequenceEither :: SemiIso (r, Either a b) (Either (r, a) (r, b))
206+siSequenceEither = siPure (\(r, e) -> Bi.bimap (r,) (r,) e) (either (Bi.second Left) (Bi.second Right))