-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | bidirectional arrows, bijective functions, and invariant functors
--   
--   Representations and operations for bidirectional arrows (total
--   isomorphisms: an arrow paired with its inverse). Classes for invariant
--   functors and monoidal functors. Includes a number of useful bijections
--   and operations, as well as interoperability with related packages.
--   
--   Most users will want to import one or more of <a>Data.Invertible</a>
--   qualified, <a>Control.Invertible.Monoidal</a> unqualified, and any
--   additional compatibility modules.
@package invertible
@version 0.2.0.5


-- | The base representation for bidirectional arrows (bijections).
module Data.Invertible.Bijection

-- | A representation of a bidirectional arrow (embedding-projection pair
--   of arrows transformer): an arrow and its inverse. Most uses will
--   prefer the specialized <a>&lt;-&gt;</a> type for function arrows.
--   
--   To constitute a valid bijection, <a>biTo</a> and <a>biFrom</a> should
--   be inverses:
--   
--   <ul>
--   <li><pre>biTo . biFrom = id</pre></li>
--   <li><pre>biFrom . biTo = id</pre></li>
--   </ul>
--   
--   It may be argued that the arguments should be in the opposite order
--   due to the arrow syntax, but it makes more sense to me to have the
--   forward function come first.
data Bijection (a :: * -> * -> *) b c
(:<->:) :: a b c -> a c b -> Bijection b c
[biTo] :: Bijection b c -> a b c
[biFrom] :: Bijection b c -> a c b
infix 2 :<->:

-- | Specialization of <a>Bijection</a> to function arrows. Represents both
--   a function, <tt>f</tt>, and its (presumed) inverse, <tt>g</tt>,
--   represented as <tt>f <a>:&lt;-&gt;:</a> g</tt>.
type (<->) = Bijection (->)
infix 2 <->
instance Control.Category.Category a => Control.Category.Category (Data.Invertible.Bijection.Bijection a)
instance Control.Arrow.Arrow a => Control.Arrow.Arrow (Data.Invertible.Bijection.Bijection a)
instance Control.Arrow.ArrowChoice a => Control.Arrow.ArrowChoice (Data.Invertible.Bijection.Bijection a)
instance Control.Arrow.ArrowZero a => Control.Arrow.ArrowZero (Data.Invertible.Bijection.Bijection a)
instance Data.Semigroupoid.Semigroupoid a => Data.Semigroupoid.Semigroupoid (Data.Invertible.Bijection.Bijection a)
instance Data.Semigroupoid.Semigroupoid a => Data.Groupoid.Groupoid (Data.Invertible.Bijection.Bijection a)
instance Data.Functor.Invariant.Invariant (Data.Invertible.Bijection.Bijection (->) b)
instance Data.Functor.Invariant.Invariant2 (Data.Invertible.Bijection.Bijection (->))


-- | Bidirectional arrows. Taken directly from
--   
--   <ul>
--   <li>Artem Alimarine, et al. <i>There and Back Again: Arrows for
--   Invertible Programming</i>. Haskell '05.
--   <a>http://citeseer.ist.psu.edu/alimarine05there.html</a></li>
--   </ul>
module Control.Invertible.BiArrow

-- | The bidirectional arrow class.
--   
--   Instances should satisfy the following laws:
--   
--   <ul>
--   <li><pre>f1 &lt;-&gt; g2 &gt;&gt;&gt; g1 &lt;-&gt; f2 = (f1
--   &gt;&gt;&gt; g1) &lt;-&gt; (f2 &gt;&gt;&gt; g2)</pre></li>
--   <li><pre>invert (invert f) = f</pre></li>
--   <li><pre>invert (f &lt;-&gt; g) = g &lt;-&gt; f</pre></li>
--   <li><pre>first (f &lt;-&gt; g) = f *** id &lt;-&gt; g ***
--   id</pre></li>
--   <li><pre>first h &gt;&gt;&gt; id *** f &lt;-&gt; id *** g = id *** f
--   &lt;-&gt; id *** g &gt;&gt;&gt; first h</pre></li>
--   <li><pre>first (first f) &gt;&gt;&gt; assoc = assoc &gt;&gt;&gt; first
--   f</pre></li>
--   </ul>
--   
--   where <tt>assoc = [<a>biCase</a>|((x,y),z) &lt;-&gt; (x,(y,z))|]</tt>
class (Groupoid a, Category a) => BiArrow a

-- | Take two functions and lift them into a bidirectional arrow. The
--   intention is that these functions are each other's inverse.
(<->) :: BiArrow a => (b -> c) -> (c -> b) -> a b c

-- | Inverse: reverse the direction of a bidirectional arrow.
invert :: BiArrow a => a b c -> a c b
infix 2 <->

-- | Bidirectional arrows under <a>Arrow</a>.
--   
--   Although <a>BiArrow</a> should not, strictly speaking, be a subclass
--   of <a>Arrow</a> (as it is often impossible to define <a>arr</a>), this
--   is done because (as the paper says) "conceptually bi-arrows form an
--   extension of the arrow class. Moreover, it allows us to use bi-arrows
--   as normal arrows." This class exists to register this confound.
class (BiArrow a, Arrow a) => BiArrow' a

-- | Lift a bidirectional function to an arbitrary arrow using
--   <a>BiArrow</a>.
biarr :: BiArrow a => (b <-> c) -> a b c

-- | Construct an involution (a biarrow where the function and inverse are
--   the same).
involve :: BiArrow a => (b -> b) -> a b b

-- | Precomposition with a pure bijection.
(^^>>) :: BiArrow a => (b <-> c) -> a c d -> a b d
infixr 1 ^^>>

-- | Postcomposition with a pure bijection.
(>>^^) :: BiArrow a => a b c -> (c <-> d) -> a b d
infixr 1 >>^^

-- | Precomposition with a pure bijection (right-to-left variant).
(<<^^) :: BiArrow a => a c d -> (b <-> c) -> a b d
infixr 1 <<^^

-- | Postcomposition with a pure bijection (right-to-left variant).
(^^<<) :: BiArrow a => (c <-> d) -> a b c -> a b d
infixr 1 ^^<<

-- | Bidirectional <a>Kleisli</a> monad arrow transformer.
type BiKleisli m = Bijection (Kleisli m)
instance (Data.Semigroupoid.Semigroupoid a, Control.Arrow.Arrow a) => Control.Invertible.BiArrow.BiArrow' (Data.Invertible.Bijection.Bijection a)
instance (Data.Semigroupoid.Semigroupoid a, Control.Arrow.Arrow a) => Control.Invertible.BiArrow.BiArrow (Data.Invertible.Bijection.Bijection a)
instance (Data.Semigroupoid.Semigroupoid a, Control.Arrow.Arrow a) => Control.Invertible.BiArrow.BiArrow (Data.Isomorphism.Iso a)
instance Control.Invertible.BiArrow.BiArrow Control.Isomorphism.Partial.Unsafe.Iso
instance Data.Semigroupoid.Semigroupoid Control.Isomorphism.Partial.Unsafe.Iso
instance Data.Groupoid.Groupoid Control.Isomorphism.Partial.Unsafe.Iso


-- | Bidirectional version of <a>Data.Coerce</a>.
module Data.Invertible.Coerce

-- | Safely <a>coerce</a> between values of types that have the same
--   representation.
coerce :: (Coercible a b, Coercible b a) => a <-> b


-- | Bidirectional versions of <a>Enum</a> functions.
module Data.Invertible.Enum

-- | Convert between an <a>Int</a> and an <a>Enum</a> with <a>toEnum</a>
--   and <a>fromEnum</a>.
enum :: Enum a => Int <-> a

-- | Combine <a>succ</a> and <a>pred</a>
succ :: Enum a => a <-> a


-- | Bidirectional version of <a>Data.Function</a>.
module Data.Invertible.Function

-- | Identity bijection.
id :: a <-> a

-- | Bijection composition
(.) :: (b <-> c) -> (a <-> b) -> a <-> c
infixr 9 .

-- | Bidirectional constant function (not a true bijection).
consts :: a -> b -> a <-> b

-- | Convert between '()' and a constant (not a true bijection).
const :: a -> () <-> a

-- | <a>flip</a> the order of the first two arguments of a function.
flip :: (a -> b -> c) <-> (b -> a -> c)


-- | Bidirectional version of <a>Data.Bool</a>.
module Data.Invertible.Bool

-- | Boolean <a>not</a>.
not :: Bool <-> Bool


-- | Bidirectional version of <a>Data.Bits</a>.
module Data.Invertible.Bits

-- | <a>complement</a> all the bits in the argument.
complement :: Bits a => a <-> a


-- | Use bijections on <tt>Invariant</tt> functors from
--   <a>Data.Functor.Invariant</a>.
module Data.Invertible.Invariant

-- | Apply a bijection over an <a>Invariant</a> using <a>invmap</a>.
invmap :: Invariant f => (a <-> b) -> f a -> f b


-- | Convert bijections to and from lens isomorphisms in
--   <a>Control.Lens.Iso</a>.
module Data.Invertible.Lens

-- | Convert an isomorphism to a lens.
toIso :: (a <-> b) -> Iso' a b

-- | Convert a lens to an isomorphism.
unIso :: AnIso' a b -> a <-> b


-- | Using bijections with monads.
module Data.Invertible.Monad

-- | Bind two functions to create a
--   <a>Control.Invertible.MonadArrow</a>-form bijection.
bind :: Monad m => (a -> m b) -> (b -> m a) -> m a <-> m b

-- | Crazy operator form of <a>bind</a>.
(=<<->>=) :: Monad m => (a -> m b) -> (b -> m a) -> m a <-> m b
infix 2 =<<->>=

-- | Promote a bijection to a <a>Control.Invertible.MonadArrow</a>-form
--   bijection. (Equivalent to <a>bifmap</a> and <a>biarr</a>.)
liftM :: Monad m => (a <-> b) -> m a <-> m b


-- | Convert bijections to and from (total) <a>Iso</a>.
module Data.Invertible.PartialIsomorphism

-- | Convert a bijection to a (total) partial isomorphism.
toIso :: (a <-> b) -> Iso a b

-- | Convert a partial isomorphism to a bijection by propagating
--   <a>Nothing</a>s.
fromIso :: Iso a b -> Maybe a <-> Maybe b

-- | Apply a bijection over a <a>IsoFunctor</a> using <a>&lt;$&gt;</a>.
(<$>) :: IsoFunctor f => (a <-> b) -> f a -> f b


-- | Convert bijections to and from semigroupoids <a>Iso</a>.
module Data.Invertible.Semigroupoid

-- | Convert a bijection to a semigroupoid isomorphism.
toIso :: Bijection a b c -> Iso a b c

-- | Convert a semigroupoid isomorphism to a bijection.
fromIso :: Iso a b c -> Bijection a b c


-- | Convenient construction of bidirectional functions using case-like
--   syntax.
module Data.Invertible.TH

-- | Construct an expression representing a function bijection based on a
--   set of newline- or semicolon-separated cases. Each case should be two
--   pattern-expressions separated by <tt><a>-</a></tt>. Each
--   pattern-expression is a haskell pattern that can also be interpreted
--   as an expression. You can think of these as symmetric or bidirectional
--   case expressions. The result will be a bijection that is the
--   combination of two lambdas, one with the cases intepreted forward, and
--   one reverse. For example:
--   
--   <pre>
--   newtype T a = C a
--   biC :: T a &lt;-&gt; a
--   biC = [biCase| C a &lt;-&gt; a |]
--   </pre>
--   
--   <pre>
--   isJust :: Maybe () &lt;-&gt; Bool
--   isJust = [biCase|
--       Just () &lt;-&gt; True
--       Nothing &lt;-&gt; False
--     |]
--   </pre>
biCase :: QuasiQuoter


-- | Bidirectional operations over <a>Ordering</a>.
module Data.Invertible.Ord

-- | Invert an <a>Ordering</a> (see <a>Down</a>).
down :: Ordering <-> Ordering


-- | Bidirectional transforms for <a>Data.Monoid</a>.
module Data.Invertible.Monoid

-- | The monoid of endomorphisms under composition.
newtype BiEndo a
BiEndo :: (a <-> a) -> BiEndo a
[appBiEndo] :: BiEndo a -> a <-> a

-- | (Un)wrap the <a>Dual</a> monoid.
dual :: a <-> Dual a

-- | (Un)wrap the <a>Endo</a> monoid.
endo :: (a -> a) <-> Endo a

-- | (Un)wrap the <a>BiEndo</a> monoid.
biEndo :: (a <-> a) <-> BiEndo a

-- | (Un)wrap the <a>All</a> monoid.
all :: Bool <-> All

-- | (Un)wrap the <a>Any</a> monoid.
any :: Bool <-> Any

-- | (Un)wrap the <a>Sum</a> monoid.
sum :: a <-> Sum a

-- | (Un)wrap the <a>Product</a> monoid.
product :: a <-> Product a

-- | (Un)wrap the <a>First</a> monoid.
first :: Maybe a <-> First a

-- | (Un)wrap the <a>Last</a> monoid.
last :: Maybe a <-> Last a

-- | (Un)wrap the <a>Last</a> monoid.
alt :: f a <-> Alt f a
instance GHC.Base.Semigroup (Data.Invertible.Monoid.BiEndo a)
instance GHC.Base.Monoid (Data.Invertible.Monoid.BiEndo a)


-- | This provides a subset of the functionality as the invariant package's
--   <a>Data.Functor.Invariant</a> module, but based on
--   <a>Data.Invertible</a>, without all the instances, and with an
--   interface matching <a>Data.Functor</a>.
--   
--   This module is intended to be imported qualified, e.g.,:
--   
--   <pre>
--   import qualified Control.Invertible.Functor as Inv
--   </pre>
module Control.Invertible.Functor

-- | An invariant version of <a>Functor</a>, equivalent to
--   <a>Invariant</a>.
class Functor f
fmap :: Functor f => (a <-> b) -> f a -> f b

-- | Default invertible <a>Functor</a> implementation for simple
--   non-invertible <a>Functor</a>s.
fmapDefault :: Functor f => (a <-> b) -> f a -> f b

-- | An infix synnonym for <a>fmap</a>.
(<$>) :: Functor f => (a <-> b) -> f a -> f b
infixl 4 <$>
instance (Data.Semigroupoid.Semigroupoid a, Control.Arrow.Arrow a) => Control.Invertible.Functor.Functor (Data.Invertible.Bijection.Bijection a b)
instance Control.Invertible.Functor.Functor Data.Semigroup.Internal.Endo
instance Control.Invertible.Functor.Functor Data.Invertible.Monoid.BiEndo


-- | Bidirectional version of <a>Data.Maybe</a>.
module Data.Invertible.Maybe

-- | Convert between 'Just ()' and <a>True</a> (see <a>isJust</a>).
isJust :: Maybe () <-> Bool

-- | Convert between <a>Nothing</a> and <a>True</a> (see <a>isNothing</a>).
--   (<tt><a>not</a> . <a>isJust</a></tt>)
isNothing :: Maybe () <-> Bool

-- | Convert between (the head of) a (singleton) list and <a>Maybe</a> (see
--   <a>listToMaybe</a>). (<tt><a>invert</a> <a>maybeToList</a></tt>)
listToMaybe :: [a] <-> Maybe a

-- | Convert between <a>Maybe</a> and a (singleton) list (see
--   <a>maybeToList</a>). (<tt><a>invert</a> <a>listToMaybe</a></tt>)
maybeToList :: Maybe a <-> [a]

-- | Convert between <a>Nothing</a> and a default value, or <a>Just</a> and
--   its value (not a true bijection).
fromMaybe :: Eq a => a -> Maybe a <-> a

-- | Convert between <a>Just</a> and its value.
fromJust :: Maybe a <-> a


-- | Bidirectional version of <a>Data.List</a> and other operations over
--   lists.
module Data.Invertible.List

-- | Convert between <tt><a>Just</a> (head, tail)</tt> and the non-empty
--   list <tt>head:tail</tt>.
cons :: Maybe (a, [a]) <-> [a]

-- | Convert between the non-empty list <tt>head:tail</tt> and
--   <tt><a>Just</a> (head, tail)</tt>. (<tt><a>invert</a>
--   <a>cons</a></tt>)
uncons :: [a] <-> Maybe (a, [a])

-- | Convert between <tt>(<a>Just</a> head, tail)</tt> and the non-empty
--   list <tt>head:tail</tt>, or <tt>(<a>Nothing</a>, list)</tt> and
--   <tt>list</tt>.
consMaybe :: (Maybe a, [a]) <-> [a]

-- | Combine <a>replicate</a> and <a>length</a> for unit lists.
repLen :: Int <-> [()]

-- | Apply a bijection over a list using <a>map</a>.
map :: (a <-> b) -> [a] <-> [b]

-- | <a>reverse</a> the order of a (finite) list.
reverse :: [a] <-> [a]

-- | <a>transpose</a> the rows and columns of its argument.
transpose :: [[a]] <-> [[a]]

-- | Bi-directional <a>lookup</a>.
lookup :: (Eq a, Eq b) => [(a, b)] -> Maybe a <-> Maybe b

-- | Combine <a>elemIndex</a> and safe <a>!!</a>.
index :: Eq a => [a] -> Maybe a <-> Maybe Int

-- | <a>zip</a> two lists together.
zip :: ([a], [b]) <-> [(a, b)]

-- | <a>zip3</a> three lists together.
zip3 :: ([a], [b], [c]) <-> [(a, b, c)]

-- | <a>zip4</a> four lists together.
zip4 :: ([a], [b], [c], [d]) <-> [(a, b, c, d)]

-- | <a>zip5</a> five lists together.
zip5 :: ([a], [b], [c], [d], [e]) <-> [(a, b, c, d, e)]

-- | <a>zip6</a> six lists together.
zip6 :: ([a], [b], [c], [d], [e], [f]) <-> [(a, b, c, d, e, f)]

-- | <a>zip7</a> seven lists together.
zip7 :: ([a], [b], [c], [d], [e], [f], [g]) <-> [(a, b, c, d, e, f, g)]

-- | <a>zipWith</a> two lists together using a bijection.
zipWith :: ((a, b) <-> c) -> ([a], [b]) <-> [c]

-- | (Un)interleave two lists, e.g., between <tt>([2,5,11],[3,7])</tt> and
--   <tt>[2,3,5,7,11]</tt>.
interleave :: ([a], [a]) <-> [a]

-- | Split a string into <a>lines</a>.
lines :: String <-> [String]

-- | Split a string into <a>words</a>.
words :: String <-> [String]


-- | Bidirectional version of <a>Data.Functor</a>.
module Data.Invertible.Functor

-- | Lift both sides of an bijection over a functor using <a>fmap</a>. We
--   name this bifmap in deference to the more useful <a>fmap</a>.
bifmap :: Functor f => (a <-> b) -> f a <-> f b

-- | Convert the <a>Identity</a> functor.
identity :: a <-> Identity a


-- | Bidirectional version of <a>Data.Either</a>.
module Data.Invertible.Either

-- | Convert between <a>Left</a> and <a>Right</a>.
switch :: Either a b <-> Either b a

-- | Convert between <a>Left</a> and <a>True</a> (see <a>isLeft</a>).
isLeft :: Either () () <-> Bool

-- | Convert between <a>Right</a> and <a>True</a> (see <a>isRight</a>).
--   (<tt><a>not</a> . <a>isLeft</a></tt>)
isRight :: Either () () <-> Bool

-- | Convert between <a>Left</a> and <a>Just</a>.
lft :: Either a () <-> Maybe a

-- | Convert between 'Right and <a>Just</a>.
rgt :: Either () a <-> Maybe a

-- | Lift an either out of the first component of a tuple.
eitherFirst :: Either (a, c) (b, c) <-> (Either a b, c)

-- | Lift an either out of the second component of a tuple.
eitherSecond :: Either (a, b) (a, c) <-> (a, Either b c)

-- | Pivot nested either terms between right and left (lacking a standard
--   3-sum representation).
pivotEither :: Either a (Either b c) <-> Either (Either a b) c


-- | Bidirectional version of <a>Data.Complex</a>.
module Data.Invertible.Complex

-- | Convert between <tt>Complex</tt> numbers and rectangular form.
complex :: (a, a) <-> Complex a

-- | Convert between complex numbers and <a>polar</a> form.
polar :: RealFloat a => (a, a) <-> Complex a

-- | The <a>conjugate</a> of a complex number.
conjugate :: Num a => Complex a <-> Complex a


-- | A symmetric version of the Kleisli monad transformer arrow. This
--   admits three isomorphic <a>MonadBijection</a> types:
--   
--   <ul>
--   <li><pre><a>MonadArrow</a> (<a>BiArrow</a>) m a b</pre></li>
--   <li><pre><a>Bijection</a> (<a>MonadFunction</a> m) a b</pre></li>
--   <li><pre>m a <a>BiArrow</a> m b</pre></li>
--   </ul>
--   
--   The Alimarine paper just calls it "MoT" for Monad Transformer.
module Control.Invertible.MonadArrow

-- | Bidirectional <a>Kleisli</a>-like monad arrow transformer.
newtype MonadArrow a m b c
MonadArrow :: a (m b) (m c) -> MonadArrow a m b c
[runMonadArrow] :: MonadArrow a m b c -> a (m b) (m c)

-- | Specialization of <a>MonadArrow</a> to function arrows.
type MonadFunction = MonadArrow (->)
type MonadBijection m = MonadArrow (<->) m
type MonadBijection' m = Bijection (MonadFunction m)
type MonadBijection'' m a b = m a <-> m b

-- | Convert between isomorphic representations of <a>MonadBijection</a>s.
monadBijection :: MonadBijection' m a b <-> MonadBijection m a b

-- | Convert between isomorphic representations of <a>MonadBijection</a>s.
monadBijection' :: MonadBijection'' m a b <-> MonadBijection' m a b
instance Control.Category.Category a => Control.Category.Category (Control.Invertible.MonadArrow.MonadArrow a m)
instance GHC.Base.Monad m => Control.Arrow.Arrow (Control.Invertible.MonadArrow.MonadArrow (->) m)
instance GHC.Base.Monad m => Control.Arrow.ArrowChoice (Control.Invertible.MonadArrow.MonadArrow (->) m)
instance GHC.Base.MonadPlus m => Control.Arrow.ArrowZero (Control.Invertible.MonadArrow.MonadArrow (->) m)
instance GHC.Base.MonadPlus m => Control.Arrow.ArrowPlus (Control.Invertible.MonadArrow.MonadArrow (->) m)
instance GHC.Base.Monad m => Control.Arrow.Arrow (Control.Invertible.MonadArrow.MonadArrow (Data.Invertible.Bijection.<->) m)
instance GHC.Base.Monad m => Control.Arrow.ArrowChoice (Control.Invertible.MonadArrow.MonadArrow (Data.Invertible.Bijection.<->) m)
instance GHC.Base.MonadPlus m => Control.Arrow.ArrowZero (Control.Invertible.MonadArrow.MonadArrow (Data.Invertible.Bijection.<->) m)
instance GHC.Base.MonadPlus m => Control.Arrow.ArrowPlus (Control.Invertible.MonadArrow.MonadArrow (Data.Invertible.Bijection.<->) m)
instance (Control.Invertible.BiArrow.BiArrow a, GHC.Base.Monad m) => Control.Invertible.BiArrow.BiArrow (Control.Invertible.MonadArrow.MonadArrow a m)
instance GHC.Base.Monad m => Control.Invertible.BiArrow.BiArrow' (Control.Invertible.MonadArrow.MonadArrow (Data.Invertible.Bijection.<->) m)
instance Data.Semigroupoid.Semigroupoid a => Data.Semigroupoid.Semigroupoid (Control.Invertible.MonadArrow.MonadArrow a m)
instance Data.Groupoid.Groupoid a => Data.Groupoid.Groupoid (Control.Invertible.MonadArrow.MonadArrow a m)


-- | Bidirectional version of <a>Data.Tuple</a> and other operations over
--   nested tuples.
module Data.Invertible.Tuple

-- | Extract the <a>fst</a> component of a pair.
fst :: (a, ()) <-> a

-- | Extract the <a>snd</a> component of a pair.
snd :: ((), a) <-> a

-- | Convert between an uncurried function and a <a>curry</a>ed function.
curry :: ((a, b) -> c) <-> (a -> b -> c)

-- | <a>swap</a> the components of a pair.
swap :: (a, b) <-> (b, a)
flatten1_2 :: (a, (b, c)) <-> (a, b, c)
flatten1_3 :: (a, (b, c, d)) <-> (a, b, c, d)
flatten1_4 :: (a, (b, c, d, e)) <-> (a, b, c, d, e)
flatten2_1 :: ((a, b), c) <-> (a, b, c)
flatten2_2 :: ((a, b), (c, d)) <-> (a, b, c, d)
flatten3_1 :: ((a, b, c), d) <-> (a, b, c, d)
flatten4_1 :: ((a, b, c, d), e) <-> (a, b, c, d, e)


-- | The bidirectional "Prelude", which re-exports various bijections
--   similar to functions from <a>Prelude</a>. Most "un"-functions are left
--   out for obvious reasons.
module Data.Invertible.Prelude

-- | Take two functions and lift them into a bidirectional arrow. The
--   intention is that these functions are each other's inverse.
(<->) :: BiArrow a => (b -> c) -> (c -> b) -> a b c
infix 2 <->

-- | Specialization of <a>Bijection</a> to function arrows. Represents both
--   a function, <tt>f</tt>, and its (presumed) inverse, <tt>g</tt>,
--   represented as <tt>f <a>:&lt;-&gt;:</a> g</tt>.
type (<->) = Bijection (->)
infix 2 <->

-- | Convert between '()' and a constant (not a true bijection).
const :: a -> () <-> a

-- | <a>flip</a> the order of the first two arguments of a function.
flip :: (a -> b -> c) <-> (b -> a -> c)

-- | Identity bijection.
id :: a <-> a

-- | Bijection composition
(.) :: (b <-> c) -> (a <-> b) -> a <-> c
infixr 9 .

-- | Boolean <a>not</a>.
not :: Bool <-> Bool

-- | Convert between an <a>Int</a> and an <a>Enum</a> with <a>toEnum</a>
--   and <a>fromEnum</a>.
enum :: Enum a => Int <-> a

-- | Combine <a>succ</a> and <a>pred</a>
succ :: Enum a => a <-> a

-- | Extract the <a>fst</a> component of a pair.
fst :: (a, ()) <-> a

-- | Extract the <a>snd</a> component of a pair.
snd :: ((), a) <-> a

-- | Convert between an uncurried function and a <a>curry</a>ed function.
curry :: ((a, b) -> c) <-> (a -> b -> c)

-- | Convert between <tt><a>Just</a> (head, tail)</tt> and the non-empty
--   list <tt>head:tail</tt>.
cons :: Maybe (a, [a]) <-> [a]

-- | Convert between the non-empty list <tt>head:tail</tt> and
--   <tt><a>Just</a> (head, tail)</tt>. (<tt><a>invert</a>
--   <a>cons</a></tt>)
uncons :: [a] <-> Maybe (a, [a])

-- | Lift both sides of an bijection over a functor using <a>fmap</a>. We
--   name this bifmap in deference to the more useful <a>fmap</a>.
bifmap :: Functor f => (a <-> b) -> f a <-> f b

-- | An invariant version of <a>Functor</a>, equivalent to
--   <a>Invariant</a>.
class Functor f
fmap :: Functor f => (a <-> b) -> f a -> f b

-- | An infix synnonym for <a>fmap</a>.
(<$>) :: Functor f => (a <-> b) -> f a -> f b
infixl 4 <$>

-- | Apply a bijection over a list using <a>map</a>.
map :: (a <-> b) -> [a] <-> [b]

-- | <a>reverse</a> the order of a (finite) list.
reverse :: [a] <-> [a]

-- | <a>zip</a> two lists together.
zip :: ([a], [b]) <-> [(a, b)]

-- | <a>zip3</a> three lists together.
zip3 :: ([a], [b], [c]) <-> [(a, b, c)]

-- | <a>zipWith</a> two lists together using a bijection.
zipWith :: ((a, b) <-> c) -> ([a], [b]) <-> [c]

-- | Split a string into <a>lines</a>.
lines :: String <-> [String]

-- | Split a string into <a>words</a>.
words :: String <-> [String]


-- | Bidirectional functions. The type <a>&lt;-&gt;</a> is the basis,
--   representing a bijective function between two types. Bijections can be
--   constructed from two functions with <a>&lt;-&gt;</a> or from a set of
--   Haskell cases using <a>biCase</a>.
--   
--   This and other modules in this package export functionality generally
--   mirroring that provided by the base modules, but over bijections. They
--   are thus intended to be imported qualified, e.g.,:
--   
--   <pre>
--   import qualified Data.Invertible as Inv
--   </pre>
module Data.Invertible


-- | Invariant monoidal functors.
--   
--   This roughly corresponds to <a>Control.Applicative</a>, but exposes a
--   non-overlapping API so can be imported unqualified. It does, however,
--   use operators similar to those provided by contravariant.
module Control.Invertible.Monoidal

-- | A representation of a bidirectional arrow (embedding-projection pair
--   of arrows transformer): an arrow and its inverse. Most uses will
--   prefer the specialized <a>&lt;-&gt;</a> type for function arrows.
--   
--   To constitute a valid bijection, <a>biTo</a> and <a>biFrom</a> should
--   be inverses:
--   
--   <ul>
--   <li><pre>biTo . biFrom = id</pre></li>
--   <li><pre>biFrom . biTo = id</pre></li>
--   </ul>
--   
--   It may be argued that the arguments should be in the opposite order
--   due to the arrow syntax, but it makes more sense to me to have the
--   forward function come first.
data Bijection (a :: * -> * -> *) b c
(:<->:) :: a b c -> a c b -> Bijection b c
[biTo] :: Bijection b c -> a b c
[biFrom] :: Bijection b c -> a c b
infix 2 :<->:

-- | Construct an expression representing a function bijection based on a
--   set of newline- or semicolon-separated cases. Each case should be two
--   pattern-expressions separated by <tt><a>-</a></tt>. Each
--   pattern-expression is a haskell pattern that can also be interpreted
--   as an expression. You can think of these as symmetric or bidirectional
--   case expressions. The result will be a bijection that is the
--   combination of two lambdas, one with the cases intepreted forward, and
--   one reverse. For example:
--   
--   <pre>
--   newtype T a = C a
--   biC :: T a &lt;-&gt; a
--   biC = [biCase| C a &lt;-&gt; a |]
--   </pre>
--   
--   <pre>
--   isJust :: Maybe () &lt;-&gt; Bool
--   isJust = [biCase|
--       Just () &lt;-&gt; True
--       Nothing &lt;-&gt; False
--     |]
--   </pre>
biCase :: QuasiQuoter

-- | Another synonym for <a>fmap</a> to match other operators in this
--   module.
(>$<) :: Functor f => (a <-> b) -> f a -> f b
infixl 4 >$<

-- | Given a value an an invariant for that value, always provide that
--   value and ignore the produced value. <tt><a>fmap</a> . flip
--   <a>consts</a> ()</tt>
(>$) :: Functor f => a -> f a -> f ()
infixl 4 >$

-- | <pre>
--   flip (<a>&gt;$</a>)
--   </pre>
($<) :: Functor f => f a -> a -> f ()
infixl 4 $<

-- | Invariant monoidal functor. This roughly corresponds to
--   <a>Applicative</a>, which, for covariant functors, is equivalent to a
--   monoidal functor. Invariant functors, however, may admit a monoidal
--   instance but not applicative.
class Functor f => Monoidal f

-- | Lift a unit value, analogous to <tt><a>pure</a> ()</tt> (but also like
--   <tt>const ()</tt>).
unit :: Monoidal f => f ()

-- | Merge two functors into a tuple, analogous to <tt><a>liftA2</a>
--   (,)</tt>. (Sometimes known as <tt>**</tt>.)
(>*<) :: Monoidal f => f a -> f b -> f (a, b)
infixl 4 >*<

-- | Default <a>unit</a> implementation for non-invertible
--   <a>Applicative</a>s.
unitDefault :: Applicative f => f ()

-- | Default '&gt;*&lt; implementation for non-invertible
--   <a>Applicative</a>s.
pairADefault :: Applicative f => f a -> f b -> f (a, b)

-- | Sequence actions, discarding/inhabiting the unit value of the second
--   argument.
(>*) :: Monoidal f => f a -> f () -> f a
infixl 4 >*

-- | Sequence actions, discarding/inhabiting the unit value of the first
--   argument.
(*<) :: Monoidal f => f () -> f a -> f a
infixl 4 *<

-- | Lift an (uncurried) bijection into a monoidal functor.
liftI2 :: Monoidal f => ((a, b) <-> c) -> f a -> f b -> f c
liftI3 :: Monoidal f => ((a, b, c) <-> d) -> f a -> f b -> f c -> f d
liftI4 :: Monoidal f => ((a, b, c, d) <-> e) -> f a -> f b -> f c -> f d -> f e
liftI5 :: Monoidal f => ((a, b, c, d, e) <-> g) -> f a -> f b -> f c -> f d -> f e -> f g
(>*<<) :: Monoidal f => f a -> f (b, c) -> f (a, b, c)
infixr 3 >*<<
(>*<<<) :: Monoidal f => f a -> f (b, c, d) -> f (a, b, c, d)
infixr 3 >*<<<
(>*<<<<) :: Monoidal f => f a -> f (b, c, d, e) -> f (a, b, c, d, e)
infixr 3 >*<<<<
(>>*<) :: Monoidal f => f (a, b) -> f c -> f (a, b, c)
infixl 4 >>*<
(>>>*<) :: Monoidal f => f (a, b, c) -> f d -> f (a, b, c, d)
infixl 4 >>>*<
(>>>>*<) :: Monoidal f => f (a, b, c, d) -> f e -> f (a, b, c, d, e)
infixl 4 >>>>*<
(>>*<<) :: Monoidal f => f (a, b) -> f (c, d) -> f (a, b, c, d)
infix 3 >>*<<

-- | A constant monoidal (like <a>pure</a>), which always produces the same
--   value and ignores everything.
pureI :: Monoidal f => a -> f a

-- | Supply a constant value to a monoidal and ignore whatever is produced.
constI :: Monoidal f => a -> f a -> f ()

-- | Sequence (like <a>sequenceA_</a>) a list of monoidals, ignoring
--   (<tt><a>const</a> ()</tt>) all the results.
sequenceI_ :: (Foldable t, Monoidal f) => t (f ()) -> f ()

-- | Map each element to a monoidal and <a>sequenceI_</a> the results.
mapI_ :: (Foldable t, Monoidal f) => (a -> f ()) -> t a -> f ()

-- | <pre>
--   flip <a>mapI_</a>
--   </pre>
forI_ :: (Foldable t, Monoidal f) => t a -> (a -> f ()) -> f ()

-- | Sequence (like <a>sequenceA</a>) and filter (like <a>catMaybes</a>) a
--   list of monoidals, producing the list of non-<a>Nothing</a> values.
--   Shorter input lists pad with <a>Nothing</a>s and longer ones are
--   ignored.
sequenceMaybesI :: Monoidal f => [f (Maybe a)] -> f [a]

-- | Map each element to a <a>Maybe</a> monoidal and sequence the results
--   (like <a>traverse</a> and <a>mapMaybe</a>).
mapMaybeI :: Monoidal f => (a -> f (Maybe b)) -> [a] -> f [b]

-- | Monoidal functors that allow choice.
class Monoidal f => MonoidalAlt f

-- | An always-failing (and thus impossible) value.
zero :: MonoidalAlt f => f Void

-- | Associative binary choice.
(>|<) :: MonoidalAlt f => f a -> f b -> f (Either a b)
infixl 3 >|<

-- | Default <a>&gt;|&lt;</a> implementation for non-invertible
--   <a>Alternative</a>s.
eitherADefault :: Alternative f => f a -> f b -> f (Either a b)

-- | Assymetric (and therefore probably not bijective) version of
--   <a>&gt;|&lt;</a> that returns whichever action succeeds but always
--   uses the left one on inputs.
(>|) :: MonoidalAlt f => f a -> f a -> f a
infixl 3 >|

-- | Assymetric (and therefore probably not bijective) version of
--   <a>&gt;|&lt;</a> that returns whichever action succeeds but always
--   uses the right one on inputs.
(|<) :: MonoidalAlt f => f a -> f a -> f a
infixl 3 |<

-- | Analogous to <a>optional</a>: always succeeds.
optionalI :: MonoidalAlt f => f a -> f (Maybe a)

-- | Return a default value if a monoidal functor fails, and only apply it
--   to non-default values.
defaulting :: (MonoidalAlt f, Eq a) => a -> f a -> f a

-- | Repeatedly apply a monoidal functor until it fails. Analogous to
--   <a>many</a>.
manyI :: MonoidalAlt f => f a -> f [a]

-- | Try a list of monoidal actions in sequence, producing the index of the
--   first successful action, and evaluating the action with the given
--   index.
msumIndex :: MonoidalAlt f => [f ()] -> f Int

-- | Fold a structure with <a>&gt;|</a> (<a>|&lt;</a>), thus always
--   applying the input to the first (last) item for generation.
msumFirst :: (MonoidalAlt f, Traversable t) => t (f a) -> f a

-- | Fold a structure with <a>&gt;|</a> (<a>|&lt;</a>), thus always
--   applying the input to the first (last) item for generation.
msumLast :: (MonoidalAlt f, Traversable t) => t (f a) -> f a

-- | Take a list of items and apply them to the action in sequence until
--   one succeeds and return the cooresponding item; match the input with
--   the list and apply the corresponding action (or produce an error if
--   the input is not an element of the list).
oneOfI :: (MonoidalAlt f, Eq a) => (a -> f ()) -> [a] -> f a
instance Control.Invertible.Monoidal.Monoidal m => Control.Invertible.Monoidal.MonoidalAlt (Control.Monad.Trans.Maybe.MaybeT m)
instance Control.Invertible.Monoidal.Monoidal (Data.Invertible.Bijection.Bijection (->) ())
instance Control.Invertible.Monoidal.Monoidal m => Control.Invertible.Monoidal.Monoidal (Control.Monad.Trans.Maybe.MaybeT m)
instance Control.Invertible.Functor.Functor m => Control.Invertible.Functor.Functor (Control.Monad.Trans.Maybe.MaybeT m)


-- | A vague analog of free monads for invariant monoidals. This can
--   provide a simple basis for things like invertible parsers.
module Control.Invertible.Monoidal.Free

-- | Produce a <a>MonoidalAlt</a> out of any type constructor, simply by
--   converting each monoidal operation into a constructor. Although a
--   version more analogous to a free monad could be defined for instances
--   of <a>Functor</a> and restricted to <a>Monoidal</a>, including the
--   Yoneda transform makes this the more general case.
data Free f a
[Void] :: Free f Void
[Empty] :: Free f ()
[Free] :: !f a -> Free f a
[Join] :: Free f a -> Free f b -> Free f (a, b)
[Choose] :: Free f a -> Free f b -> Free f (Either a b)
[Transform] :: (a <-> b) -> Free f a -> Free f b

-- | Construct a string representation of a <a>Free</a> structure, given a
--   way to show any <tt>f a</tt>.
showsFree :: (forall a'. f a' -> ShowS) -> Free f a -> ShowS

-- | Transform the type constructor within a <a>Free</a>.
mapFree :: (forall a'. f a' -> m a') -> Free f a -> Free m a

-- | Given a way to extract a <tt>b</tt> from any <tt>f a</tt>, use a
--   <a>Free</a> applied to a value to produce a <tt>b</tt> by converting
--   <a>&gt;*&lt;</a> to <a>&lt;&gt;</a>.
foldFree :: Monoid b => (forall a'. f a' -> a' -> b) -> Free f a -> a -> b

-- | <a>foldFree</a> over Alternative rather than Monoid.
produceFree :: Alternative m => (forall a'. f a' -> a' -> b) -> Free f a -> a -> m b

-- | Evaluate a <a>Free</a> into an underlying <a>Alternative</a>, by
--   evaluating <a>&gt;|&lt;</a> with <a>&lt;|&gt;</a>.
runFree :: Alternative f => Free f a -> f a

-- | Given a way to convert <tt>b</tt> elements into any <tt>f a</tt>, use
--   a <a>Free</a> to parse a list of <tt>b</tt> elements into a value.
--   This just uses <a>unconsState</a> with <a>runFree</a>, and is the
--   inverse of <a>produceFree</a>, provided the given conversions are
--   themselves inverses.
parseFree :: MonadPlus m => (forall a'. f a' -> b -> m a') -> Free f a -> [b] -> m (a, [b])

-- | Flip the effective order of each <a>&gt;*&lt;</a> operation in a
--   <a>Free</a>, so that processing is done in the reverse order. It
--   probably goes without saying, but applying this to an infinite
--   structure, such as those produced by <a>manyI</a>, will not terminate.
reverseFree :: Free f a -> Free f a

-- | Convert a <a>Free</a> to Transform Normal Form: extract and merge all
--   the <a>Transform</a>, if any, to a single <a>Transform</a> at the top.
freeTNF :: Free f a -> Free f a

-- | Convert a <a>Free</a> to Transform Disjunctive Normal Form: reorder
--   the terms so thet at most one <a>Transform</a> is on the outside,
--   followed by <a>Choose</a> terms, which are above all <a>Join</a>
--   terms', with <a>Empty</a> and <a>Free</a> as leaves. Since each
--   <a>Join</a> above a <a>Choose</a> creates a duplicate <a>Join</a>
--   term, the complexity and result size can be exponential (just as with
--   boolean logic DNF).
freeTDNF :: Free f a -> Free f a

-- | Equivalent to <a>freeTDNF</a>, but also sorts the terms within each
--   <a>Join</a> clause to conform to the given ordering. The resulting
--   <a>Join</a> trees will be right-linearized (<tt>Join x (Join y (Join z
--   ...))</tt> such that <tt>x &lt;= y</tt>, <tt>y &lt;= z</tt>, etc. THis
--   performs a <i>O(n^2)</i> bubble sort on the already exponential TDNF.
sortFreeTDNF :: (forall a' b'. f a' -> f b' -> Ordering) -> Free f a -> Free f a
instance GHC.Show.Show Control.Invertible.Monoidal.Free.Underscore
instance (GHC.Base.Functor f, Data.Functor.Classes.Show1 f) => GHC.Show.Show (Control.Invertible.Monoidal.Free.Free f a)
instance Control.Invertible.Functor.Functor (Control.Invertible.Monoidal.Free.Free f)
instance Control.Invertible.Monoidal.Monoidal (Control.Invertible.Monoidal.Free.Free f)
instance Control.Invertible.Monoidal.MonoidalAlt (Control.Invertible.Monoidal.Free.Free f)
