@@ -2,13 +2,14 @@
22{-# LANGUAGE ConstraintKinds #-}
33{- |
44Module : Control.SIArrow
5−Description : Semi-iso arrows.
5+Description : Categories of reversible computations.
66Copyright : (c) Paweł Nowak
77License : MIT
88
99Maintainer : Paweł Nowak <pawel834@gmail.com>
1010Stability : experimental
1111
12+Categories of reversible computations.
1213-}
1314module Control.SIArrow (
1415 -- * Arrow.
@@ -43,18 +44,33 @@ infixr 1 ^>>, >>^
4344infixr 1 ^<<, <<^
4445infixl 4 /$/, /$~
4546infixl 5 /*/, */, /*
47+infixl 3 /?/
4648
47−-- Categories.
48−
49+-- | A category equipped with an embedding 'siarr' from @SemiIso@ into @cat@ and some
50+-- additional structure.
51+--
52+-- SIArrow abstracts categories of reversible computations
53+-- (with reversible side effects).
54+--
55+-- The category @cat@ should contain @SemiIso@ as a sort of
56+-- \"subcategory of pure computations\".
4957class (Products cat, Coproducts cat, CatPlus cat) => SIArrow cat where
58+ -- | Allows you to lift a SemiIso into @cat@. The resulting arrow should be
59+ -- in some sense minimal or \"pure\", similiar to 'pure', 'return' and
60+ -- 'arr' from "Control.Category".
5061 siarr :: ASemiIso' a b -> cat a b
5162
63+ -- | Reversed version of 'siarr'.
64+ --
65+ -- Use this where you would use 'pure'.
5266 sipure :: ASemiIso' b a -> cat a b
5367 sipure = siarr . rev
5468
69+ -- | @sisome v@ repeats @v@ as long as possible, but no less then once.
5570 sisome :: cat () b -> cat () [b]
5671 sisome v = _Cons /$/ v /*/ simany v
5772
73+ -- | @simany v@ repeats @v@ as long as possible.
5874 simany :: cat () b -> cat () [b]
5975 simany v = sisome v /+/ sipure _Empty
6076
@@ -66,41 +82,63 @@ instance MonadPlus m => SIArrow (Kleisli m) where
6682instance SIArrow ReifiedSemiIso' where
6783 siarr = reifySemiIso
6884
85+-- | Composes a SemiIso with an arrow.
6986(^>>) :: SIArrow cat => ASemiIso' a b -> cat b c -> cat a c
7087f ^>> a = a . siarr f
7188
89+-- | Composes an arrow with a SemiIso.
7290(>>^) :: SIArrow cat => cat a b -> ASemiIso' b c -> cat a c
7391a >>^ f = siarr f . a
7492
93+-- | Composes a SemiIso with an arrow, backwards.
7594(^<<) :: SIArrow cat => ASemiIso' b c -> cat a b -> cat a c
7695f ^<< a = siarr f . a
7796
97+-- | Composes an arrow with a SemiIso, backwards.
7898(<<^) :: SIArrow cat => cat b c -> ASemiIso' a b -> cat a c
7999a <<^ f = a . siarr f
80100
101+-- | Postcomposes an arrow with a reversed SemiIso. The analogue of '<$>'.
81102(/$/) :: SIArrow cat => ASemiIso' b' b -> cat a b -> cat a b'
82103ai /$/ f = sipure ai . f
83104
84−-- | > ai /$~ f = ai . morphed /$/ f
105+-- | Convenient fmap.
106+--
107+-- > ai /$~ f = ai . morphed /$/ f
85108--
86109-- This operator handles all the hairy stuff with uncurried application:
87110-- it reassociates the argument tuple and removes unnecessary (or adds necessary)
88111-- units to match the function type. You don't have to use @/*@ and @*/@ with this
89−-- operator.
112+-- operator.
90113(/$~) :: (SIArrow cat, HFoldable b', HFoldable b,
91114 HUnfoldable b', HUnfoldable b, Rep b' ~ Rep b)
92115 => ASemiIso' a b' -> cat c b -> cat c a
93116ai /$~ h = cloneSemiIso ai . morphed /$/ h
94117
118+-- | The product of two arrows with duplicate units removed. Side effect are
119+-- sequenced from left to right.
120+--
121+-- The uncurried analogue of '<*>'.
95122(/*/) :: SIArrow cat => cat () b -> cat () c -> cat () (b, c)
96123a /*/ b = unit ^>> (a *** b)
97124
125+-- | The product of two arrows, where the second one has no input and no output
126+-- (but can have side effects), with duplicate units removed. Side effect are
127+-- sequenced from left to right.
128+--
129+-- The uncurried analogue of '<*'.
98130(/*) :: SIArrow cat => cat () a -> cat () () -> cat () a
99131f /* g = unit /$/ f /*/ g
100132
133+-- | The product of two arrows, where the first one has no input and no output
134+-- (but can have side effects), with duplicate units removed. Side effect are
135+-- sequenced from left to right.
136+--
137+-- The uncurried analogue of '*>'.
101138(*/) :: SIArrow cat => cat () () -> cat () a -> cat () a
102139f */ g = unit . swapped /$/ f /*/ g
103140
141+-- | An arrow that fails with an error message.
104142sifail :: SIArrow cat => String -> cat a b
105143sifail = siarr . alwaysFailing
106144