Documentation.

This commit is contained in:
Paweł Nowak 2014-12-11 21:26:20 +01:00
parent 98d70902f3
commit 23f67c0667
3 changed files with 64 additions and 7 deletions

View File

@ -28,12 +28,20 @@ infixl 3 /+/
-- | A category with finite products.
class Category cat => Products cat where
-- | Send the first component of the input through the argument arrow, and copy the rest unchanged to the output.
--
-- @first a@ is equal to @a *** id@.
first :: cat a b -> cat (a, c) (b, c)
first a = a *** id
-- | A mirror image of 'first'.
--
-- @second a@ is equal to @id *** a@.
second :: cat a b -> cat (c, a) (c, b)
second a = id *** a
-- | A product of two arrows.
-- Split the input between the two argument arrows and combine their output.
(***) :: cat a b -> cat c d -> cat (a, c) (b, d)
a *** b = first a >>> second b
@ -44,12 +52,20 @@ instance Monad m => Products (Kleisli m) where
-- | A category with finite coproducts.
class Category cat => Coproducts cat where
-- | Feed marked inputs through the argument arrow, passing the rest through unchanged to the output.
--
-- @left a@ is equal to @a +++ id@.
left :: cat a b -> cat (Either a c) (Either b c)
left a = a +++ id
-- | A mirror image of left.
--
-- @right a@ is equal to @id +++ a@.
right :: cat a b -> cat (Either c a) (Either c b)
right a = id +++ a
-- | A coproduct of two arrows.
-- Split the input between the two argument arrows, retagging and merging their outputs.
(+++) :: cat a b -> cat c d -> cat (Either a c) (Either b d)
a +++ b = left a >>> right b
@ -60,7 +76,9 @@ instance Monad m => Coproducts (Kleisli m) where
-- | A category @cat@ is a CatPlus when @cat a b@ is a monoid for all a, b.
class Category cat => CatPlus cat where
-- | The identity of '/+/'.
cempty :: cat a b
-- | An associative operation on arrows.
(/+/) :: cat a b -> cat a b -> cat a b
{-# MINIMAL cempty, (/+/) #-}
@ -71,6 +89,7 @@ instance MonadPlus m => CatPlus (Kleisli m) where
-- | A category transformer.
class CategoryTrans t where
-- | Lift an arrow from the base category.
clift :: Category cat => cat a b -> t cat a b
{-# MINIMAL clift #-}

View File

@ -2,13 +2,14 @@
{-# LANGUAGE ConstraintKinds #-}
{- |
Module : Control.SIArrow
Description : Semi-iso arrows.
Description : Categories of reversible computations.
Copyright : (c) Paweł Nowak
License : MIT
Maintainer : Paweł Nowak <pawel834@gmail.com>
Stability : experimental
Categories of reversible computations.
-}
module Control.SIArrow (
-- * Arrow.
@ -43,18 +44,33 @@ infixr 1 ^>>, >>^
infixr 1 ^<<, <<^
infixl 4 /$/, /$~
infixl 5 /*/, */, /*
infixl 3 /?/
-- Categories.
-- | A category equipped with an embedding 'siarr' from @SemiIso@ into @cat@ and some
-- additional structure.
--
-- SIArrow abstracts categories of reversible computations
-- (with reversible side effects).
--
-- The category @cat@ should contain @SemiIso@ as a sort of
-- \"subcategory of pure computations\".
class (Products cat, Coproducts cat, CatPlus cat) => SIArrow cat where
-- | Allows you to lift a SemiIso into @cat@. The resulting arrow should be
-- in some sense minimal or \"pure\", similiar to 'pure', 'return' and
-- 'arr' from "Control.Category".
siarr :: ASemiIso' a b -> cat a b
-- | Reversed version of 'siarr'.
--
-- Use this where you would use 'pure'.
sipure :: ASemiIso' b a -> cat a b
sipure = siarr . rev
-- | @sisome v@ repeats @v@ as long as possible, but no less then once.
sisome :: cat () b -> cat () [b]
sisome v = _Cons /$/ v /*/ simany v
-- | @simany v@ repeats @v@ as long as possible.
simany :: cat () b -> cat () [b]
simany v = sisome v /+/ sipure _Empty
@ -66,41 +82,63 @@ instance MonadPlus m => SIArrow (Kleisli m) where
instance SIArrow ReifiedSemiIso' where
siarr = reifySemiIso
-- | Composes a SemiIso with an arrow.
(^>>) :: SIArrow cat => ASemiIso' a b -> cat b c -> cat a c
f ^>> a = a . siarr f
-- | Composes an arrow with a SemiIso.
(>>^) :: SIArrow cat => cat a b -> ASemiIso' b c -> cat a c
a >>^ f = siarr f . a
-- | Composes a SemiIso with an arrow, backwards.
(^<<) :: SIArrow cat => ASemiIso' b c -> cat a b -> cat a c
f ^<< a = siarr f . a
-- | Composes an arrow with a SemiIso, backwards.
(<<^) :: SIArrow cat => cat b c -> ASemiIso' a b -> cat a c
a <<^ f = a . siarr f
-- | Postcomposes an arrow with a reversed SemiIso. The analogue of '<$>'.
(/$/) :: SIArrow cat => ASemiIso' b' b -> cat a b -> cat a b'
ai /$/ f = sipure ai . f
-- | > ai /$~ f = ai . morphed /$/ f
-- | Convenient fmap.
--
-- > ai /$~ f = ai . morphed /$/ f
--
-- This operator handles all the hairy stuff with uncurried application:
-- it reassociates the argument tuple and removes unnecessary (or adds necessary)
-- units to match the function type. You don't have to use @/*@ and @*/@ with this
-- operator.
-- operator.
(/$~) :: (SIArrow cat, HFoldable b', HFoldable b,
HUnfoldable b', HUnfoldable b, Rep b' ~ Rep b)
=> ASemiIso' a b' -> cat c b -> cat c a
ai /$~ h = cloneSemiIso ai . morphed /$/ h
-- | The product of two arrows with duplicate units removed. Side effect are
-- sequenced from left to right.
--
-- The uncurried analogue of '<*>'.
(/*/) :: SIArrow cat => cat () b -> cat () c -> cat () (b, c)
a /*/ b = unit ^>> (a *** b)
-- | The product of two arrows, where the second one has no input and no output
-- (but can have side effects), with duplicate units removed. Side effect are
-- sequenced from left to right.
--
-- The uncurried analogue of '<*'.
(/*) :: SIArrow cat => cat () a -> cat () () -> cat () a
f /* g = unit /$/ f /*/ g
-- | The product of two arrows, where the first one has no input and no output
-- (but can have side effects), with duplicate units removed. Side effect are
-- sequenced from left to right.
--
-- The uncurried analogue of '*>'.
(*/) :: SIArrow cat => cat () () -> cat () a -> cat () a
f */ g = unit . swapped /$/ f /*/ g
-- | An arrow that fails with an error message.
sifail :: SIArrow cat => String -> cat a b
sifail = siarr . alwaysFailing

View File

@ -25,10 +25,10 @@ description: Semi-isomorphisms are partial isomorphisms with weakened is
dreaded @arr@).
SIArrow abstracts categories of reversible computations (with reversible side effects). In
the case of parsing and pretty-printing using the "syntax" library if we have an arrow
the case of parsing and pretty-printing using the "syntax" library if we have an arrow
@SIArrow cat => cat a b@ then we can:
.
* Evaluate it from left to right, turning a value of type @a@ into a value of type @b@,
* Evaluate it from left to right, turning a value of type @a@ into a value of type @b@,
with the side effect of consuming a sequence. (Parsing)
.
* Evaluate it from right to left, turning a value of type @b@ into a value of type @a@,