Semi-isomorphisms are partial isomorphisms with weakened iso laws. They are a basic
building block of reversible computations. And they work with Iso and Prism from `lens`

!

The module `Control.Lens.SemiIso`

defines semi-isomorphisms and provides some
basic semi-isos and combinators. A `SemiIso' a b`

can be applied in both directions
to get a `a -> Either String b`

and `b -> Either String a`

. SemiIsos can be composed
with Isos and Prisms (to get another SemiIso). Isos and Prisms can be directly
used as SemiIsos.

Semi-isomorphisms obey weaker laws then isomorphisms. We require only

```
apply f >=> unapply f >=> apply f = apply f
unapply f >=> apply f >=> unapply f = unapply f
```

instead of

```
apply f >=> unapply f = f
unapply f >=> apply f = f
```

Modules `Control.SIArrow`

and `Control.Category.Structures`

define an `Arrow`

-like class
hierarchy. Unfortunately `Control.Arrow`

cannot be used, as it is too restrictive (the
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
`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`

,
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`

,
with the side effect of generating a sequence. (Pretty-printing)

In the particular case of parsing/pretty-printing the type `a`

will be usually `()`

, e.g.
we just produce a value during parsing and just consume a value during pretty-printing.
To support this style we define a functor and applicative structure on `cat () b`

, for example
`/*/`

(equivalent of `<*>`

) has type `(/*/) :: SIArrow cat => cat () a -> cat () b -> cat () (a, b)`

.

When more power then applicative is needed - for example when the syntax depends on the
parsed value - we turn back to arrow composition.

Module `Control.Category.Reader`

defines a Reader category transformer. It is like a monad
transformer, but for categories. The next version will include some more transformers and
mtl-style classes.