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


-- | Function combinator "between" and derived combinators
--   
--   It turns out that this combinator
--   
--   <pre>
--   f ~@~ g = (f .) . (. g)
--   </pre>
--   
--   is a powerful thing. It was abstracted from following (commonly used)
--   pattern <tt>f . h . g</tt> where <tt>f</tt> and <tt>g</tt> are fixed.
--   
--   This library not only defines <tt>~@~</tt> combinator, but also some
--   derived combinators that can help us easily define a lot of things
--   including lenses. See <a>lens package</a> for detais on what lenses
--   are.
--   
--   Function <tt>Data.Function.on</tt> can be implemented using
--   <tt>~@~</tt> as:
--   
--   <pre>
--   on :: (b -&gt; b -&gt; c) -&gt; (a -&gt; b) -&gt; a -&gt; a -&gt; c
--   on f g = (id ~@~ g ~@~ g) f
--   </pre>
--   
--   If function <tt>on3</tt> existed in <i>base</i> then it could be
--   defined as:
--   
--   <pre>
--   on3 :: (b -&gt; b -&gt; b -&gt; d) -&gt; (a -&gt; b) -&gt; a -&gt; a -&gt; a -&gt; d
--   on3 f g = (id ~@~ g ~@~ g ~@~ g) f
--   </pre>
--   
--   Other usage examples and documentation can be found in
--   <a>Data.Function.Between</a> module.
@package between
@version 0.11.0.0


-- | Definitions used by family of strict function combinators. These may
--   come handy, but clash with definitions available via <a>Prelude</a>.
--   
--   <i>Module available since version 0.11.0.0.</i>
module Data.Function.Between.Strict.Internal

-- | Strict variant of function composition. Defined as:
--   
--   <pre>
--   (f . g) x = f <a>$!</a> g <a>$!</a> x
--   </pre>
--   
--   <i>Internally used since version 0.10.0.0. Moved to</i>
--   <i><a>Data.Function.Between.Strict.Internal</a> module and exposed in
--   version</i> <i>0.11.0.0.</i>
(.) :: (b -> c) -> (a -> b) -> a -> c
infixr 9 .

-- | Strict variant of <a>flip</a>. Defined as:
--   
--   <pre>
--   <a>flip</a> f b a = f <a>$!</a> a <a>$!</a> b
--   </pre>
--   
--   <i>Since version 0.11.0.0.</i>
flip :: (a -> b -> c) -> b -> a -> c


-- | This module defines types that behave as a precursors to types defined
--   in <a>lens</a> library.
--   
--   <i>Since version 0.11.0.0.</i>
module Data.Function.Between.Types

-- | Family of types that can construct isomorphism between types.
--   
--   <i>Since version 0.11.0.0.</i>
type PreIso r s t a b = ((b -> t) -> (s -> a) -> r) -> r

-- | A simple <a>PreIso</a>.
--   
--   <i>Since version 0.11.0.0.</i>
type PreIso' r s a = PreIso r s s a a

-- | We can also view <a>PreLens</a> as a special kind of <a>PreIso</a>:
--   
--   <pre>
--   <a>PreLens</a> r s t a b = <a>PreIso</a> r s (s -&gt; t) a b
--   </pre>
--   
--   <i>Since version 0.11.0.0.</i>
type PreLens r s t a b = ((b -> s -> t) -> (s -> a) -> r) -> r

-- | A simple <a>PreLens</a>, where we can not change the type of the
--   information we are focusing on. As a consequence neither the type of
--   the container data type can be changed.
--   
--   <i>Since version 0.11.0.0.</i>
type PreLens' r s a = PreLens r s s a a

-- | We can also get <a>PrePrism</a> by specializing <a>PreIso</a>:
--   
--   <pre>
--   <a>PrePrism</a> r s t a b = <a>PreIso</a> r s t (<a>Either</a> t a) b
--   </pre>
--   
--   This fact is not surprising, since <i>Prisms</i> are actually a
--   special case of isomorphism between two types.
--   
--   Let's have a type <tt>s</tt>, and we want to extract specific
--   information out of it, but that information may not be there. Because
--   of the fact that the type <tt>s</tt> can be a sum type. Imagine e.g.
--   standard <tt>Maybe</tt> data type:
--   
--   <pre>
--   <tt>Maybe</tt> a = <a>Nothing</a> | <a>Just</a> a
--   </pre>
--   
--   How do we create something that can extrat that information from a sum
--   type, and if necessary, also reconstructs that sum type. The answer is
--   <i>Prism</i>, which is defined as an isomorphism between that type
--   <tt>s</tt> and <tt><a>Either</a> t a</tt> where <tt>a</tt> is the
--   information we want to extract and <tt>t</tt> is the rest that we
--   don't care about.
--   
--   You may have noticed, that definition of <a>PrePrism</a> contains some
--   type variables that aren't mentioned in the above definition. The
--   reason for this is that, as with <i>Lenses</i> we may want to extract
--   value of type <tt>a</tt>, but when constructing new data type we may
--   want to change the type of that value in to <tt>b</tt> and therefore
--   type <tt>s</tt> may not fit, which is the reason why we have type
--   <tt>t</tt> in there. Once again we can ilustrate this with
--   <tt>Maybe</tt>. Lets say that we have a value of <tt>s =
--   <tt>Maybe</tt> a</tt>, but if we change the type of <tt>a</tt> in to
--   <tt>b</tt>, and try to create <tt>Maybe</tt> again, then it would have
--   type <tt><tt>Maybe</tt> b = t</tt>.
--   
--   <i>Since version 0.11.0.0.</i>
type PrePrism r s t a b = ((b -> t) -> (s -> Either t a) -> r) -> r

-- | A simple <a>PrePrism</a>, where we can not change the type of the
--   information we are focusing on. As a consequence neither the type of
--   the container data type can be changed.
--   
--   If we define <a>PrePrism'</a> in terms of <a>PreIso'</a> then we have
--   even better ilustration of <i>Prism</i> concept in terms of
--   isomorphism:
--   
--   <pre>
--   <a>PrePrism'</a> r s a = <a>PreIso'</a> r s (<a>Either</a> t a)
--   </pre>
--   
--   <i>Since version 0.11.0.0.</i>
type PrePrism' r s a = PrePrism r s s a a


-- | Implementation of strict <a>between</a> combinator and its variations.
--   For introductory documentation see module <a>Data.Function.Between</a>
--   and for lazy versions import <a>Data.Function.Between.Lazy</a> module.
--   
--   All functions in this module use strict (or should I say stricter?)
--   definition of function composition:
--   
--   <pre>
--   (f . g) x = f <a>$!</a> g <a>$!</a> x
--   </pre>
--   
--   <i>Module available since version 0.10.0.0.</i>
module Data.Function.Between.Strict

-- | Core combinator of this module and we build others on top of. It also
--   has an infix form <a>~@~</a> and flipped infix form <a>~@@~</a>.
--   
--   This function Defined as:
--   
--   <pre>
--   <a>between</a> f g -&gt; (f .) . (. g)
--   </pre>
--   
--   <i>Since version 0.10.0.0.</i>
between :: (c -> d) -> (a -> b) -> (b -> c) -> a -> d

-- | Infix variant of <a>between</a>.
--   
--   Fixity is left associative and set to value 8, which is one less then
--   fixity of function composition (<tt>.</tt>).
--   
--   <i>Since version 0.10.0.0.</i>
(~@~) :: (c -> d) -> (a -> b) -> (b -> c) -> a -> d
infixl 8 ~@~

-- | Flipped variant of <a>~@~</a>, i.e. flipped infix variant of
--   <a>between</a>.
--   
--   Fixity is right associative and set to value 8, which is one less then
--   fixity of function composition (<tt>.</tt>).
--   
--   <i>Since version 0.10.0.0.</i>
(~@@~) :: (a -> b) -> (c -> d) -> (b -> c) -> a -> d
infixr 8 ~@@~

-- | As <a>~@~</a>, but first function is also parametrised with
--   <tt>a</tt>, hence the name <a>^@~</a>. Character <tt>^</tt> indicates
--   which argument is parametrised with additional argument.
--   
--   This function is defined as:
--   
--   <pre>
--   (f <a>^@~</a> g) h a -&gt; ((f <a>$!</a> a) <a>~@~</a> g)) h a
--   </pre>
--   
--   Fixity is left associative and set to value 8, which is one less then
--   fixity of function composition (<tt>.</tt>).
--   
--   <i>Since version 0.10.0.0.</i>
(^@~) :: (a -> c -> d) -> (a -> b) -> (b -> c) -> a -> d
infixl 8 ^@~

-- | Flipped variant of <a>^@~</a>.
--   
--   Fixity is right associative and set to value 8, which is one less then
--   fixity of function composition (<tt>.</tt>).
--   
--   <i>Since version 0.10.0.0.</i>
(~@@^) :: (a -> b) -> (a -> c -> d) -> (b -> c) -> a -> d
infixr 8 ~@@^

-- | Pass additional argument to first two function arguments.
--   
--   This function is defined as:
--   
--   <pre>
--   (f <a>^@~</a> g) h a b -&gt; ((f <a>$!</a> a) <a>~@~</a> (g <a>$!</a> a)) h b
--   </pre>
--   
--   See also <a>^@~</a> to note the difference, most importantly that
--   <a>^@~</a> passes the same argument to all its functional arguments.
--   Since this function uses strict function composition and strict
--   application it is not so simple to define it in terms of other
--   combinators in this package and vice versa. See lazy <a>^@~</a> for
--   details.
--   
--   Fixity is set to value 8, which is one less then of function
--   composition (<tt>.</tt>).
--   
--   <i>Since version 0.10.0.0.</i>
(^@^) :: (a -> d -> e) -> (a -> b -> c) -> (c -> d) -> a -> b -> e
infix 8 ^@^

-- | Flipped variant of <a>^@^</a>.
--   
--   Fixity is set to value 8, which is one less then of function
--   composition (<tt>.</tt>).
--   
--   <i>Since version 0.10.0.0.</i>
(^@@^) :: (a -> b -> c) -> (a -> d -> e) -> (c -> d) -> a -> b -> e
infix 8 ^@@^

-- | Apply function <tt>g</tt> to each argument of binary function and
--   <tt>f</tt> to its result. In suffix "2l" the number is equal to arity
--   of the function it accepts as a third argument and character "l" is
--   for "left associative".
--   
--   <pre>
--   <a>between2l</a> f g = (f <a>~@~</a> g) <a>~@~</a> g
--   </pre>
--   
--   Interesting observation:
--   
--   <pre>
--   (\f g -&gt; <a>between2l</a> <a>id</a> g f) === <a>on</a>
--   </pre>
--   
--   <i>Since version 0.10.0.0.</i>
between2l :: (c -> d) -> (a -> b) -> (b -> b -> c) -> a -> a -> d

-- | Apply function <tt>g</tt> to each argument of ternary function and
--   <tt>f</tt> to its result. In suffix "3l" the number is equal to arity
--   of the function it accepts as a third argument and character "l" is
--   for "left associative".
--   
--   This function is defined as:
--   
--   <pre>
--   <a>between3l</a> f g = ((f <a>~@~</a> g) <a>~@~</a> g) <a>~@~</a> g
--   </pre>
--   
--   Alternatively it can be defined using <a>between2l</a>:
--   
--   <pre>
--   <a>between3l</a> f g = <a>between2l</a> f g <a>~@~</a> g
--   </pre>
--   
--   <i>Since version 0.10.0.0.</i>
between3l :: (c -> d) -> (a -> b) -> (b -> b -> b -> c) -> a -> a -> a -> d

-- | Convenience wrapper for:
--   
--   <pre>
--   \f g -&gt; <a>fmap</a> f <a>~@~</a> <a>fmap</a> g
--   </pre>
--   
--   Name of <a>&lt;~@~&gt;</a> simply says that we apply <a>&lt;$&gt;</a>
--   (<a>fmap</a>) to both its arguments and then we apply <a>~@~</a>.
--   
--   Fixity is left associative and set to value 8, which is one less then
--   of function composition (<tt>.</tt>).
--   
--   <i>Since version 0.10.0.0.</i>
(<~@~>) :: (Functor f, Functor g) => (c -> d) -> (a -> b) -> (f b -> g c) -> f a -> g d
infix 8 <~@~>

-- | Flipped variant of <a>&lt;~@~&gt;</a>.
--   
--   Name of <a>&lt;~@@~&gt;</a> simply says that we apply <a>&lt;$&gt;</a>
--   (<a>fmap</a>) to both its arguments and then we apply <a>~@@~</a>.
--   
--   Fixity is set to value 8, which is one less then of function
--   composition (<tt>.</tt>).
--   
--   <i>Since version 0.10.0.0.</i>
(<~@@~>) :: (Functor f, Functor g) => (a -> b) -> (c -> d) -> (f b -> g c) -> f a -> g d
infix 8 <~@@~>

-- | Apply <a>fmap</a> to first argument of <a>~@~</a>. Dual to
--   <a>~@~&gt;</a> which applies <a>fmap</a> to second argument.
--   
--   Defined as:
--   
--   <pre>
--   f <a>&lt;~@~</a> g = <a>fmap</a> f <a>~@~</a> g
--   </pre>
--   
--   This function allows us to define lenses mostly for pair of functions
--   that form an isomorphism. See section <a>Constructing Lenses</a> for
--   details.
--   
--   Name of <a>&lt;~@~</a> simply says that we apply <a>&lt;$&gt;</a>
--   (<a>fmap</a>) to first (left) argument and then we apply <a>~@~</a>.
--   
--   Fixity is left associative and set to value 8, which is one less then
--   of function composition (<tt>.</tt>).
--   
--   <i>Since version 0.10.0.0.</i>
(<~@~) :: Functor f => (c -> d) -> (a -> b) -> (b -> f c) -> a -> f d
infixl 8 <~@~

-- | Flipped variant of <a>&lt;~@~</a>.
--   
--   This function allows us to define lenses mostly for pair of functions
--   that form an isomorphism. See section <a>Constructing Lenses</a> for
--   details.
--   
--   Name of <a>~@@~&gt;</a> simply says that we apply <a>&lt;$&gt;</a>
--   (<a>fmap</a>) to second (right) argument and then we apply
--   <a>~@@~</a>.
--   
--   Fixity is right associative and set to value 8, which is one less then
--   fixity of function composition (<tt>.</tt>).
--   
--   <i>Since version 0.10.0.0.</i>
(~@@~>) :: Functor f => (a -> b) -> (c -> d) -> (b -> f c) -> a -> f d
infixr 8 ~@@~>

-- | Apply <a>fmap</a> to second argument of <a>~@~</a>. Dual to
--   <a>&lt;~@~</a> which applies <a>fmap</a> to first argument.
--   
--   Defined as:
--   
--   <pre>
--   f <a>~@~&gt;</a> g -&gt; f <a>~@~</a> <a>fmap</a> g
--   </pre>
--   
--   Name of <a>~@~&gt;</a> simply says that we apply <a>&lt;$&gt;</a>
--   (<a>fmap</a>) to second (right) argument and then we apply <a>~@~</a>.
--   
--   Fixity is right associative and set to value 8, which is one less then
--   of function composition (<tt>.</tt>).
--   
--   <i>Since version 0.10.0.0.</i>
(~@~>) :: Functor f => (c -> d) -> (a -> b) -> (f b -> c) -> f a -> d
infixl 8 ~@~>

-- | Flipped variant of <a>~@~&gt;</a>.
--   
--   Name of <a>&lt;~@@~</a> simply says that we apply <a>&lt;$&gt;</a>
--   (<a>fmap</a>) to first (left) argument and then we apply <a>~@@~</a>.
--   
--   Fixity is left associative and set to value 8, which is one less then
--   fixity of function composition (<tt>.</tt>).
--   
--   <i>Since version 0.10.0.0.</i>
(<~@@~) :: Functor f => (a -> b) -> (c -> d) -> (f b -> c) -> f a -> d
infixr 8 <~@@~

-- | Convenience wrapper for: <tt>\f g -&gt; <a>fmap</a> . f '^</tt>~' g@.
--   
--   This function has the same functionality as function
--   
--   <pre>
--   lens :: (s -&gt; a) -&gt; (s -&gt; b -&gt; t) -&gt; Lens s t a b
--   </pre>
--   
--   Which is defined in <a>lens package</a>. Only difference is that
--   arguments of <a>&lt;^@~</a> are flipped. See also section
--   <a>Constructing Lenses</a>.
--   
--   Name of <a>&lt;^@~</a> simply says that we apply <a>&lt;$&gt;</a>
--   (<a>fmap</a>) to first (left) arguments and then we apply <a>^@~</a>.
--   
--   Fixity is left associative and set to value 8, which is one less then
--   of function composition (<tt>.</tt>).
--   
--   <i>Since version 0.10.0.0.</i>
(<^@~) :: Functor f => (a -> c -> d) -> (a -> b) -> (b -> f c) -> a -> f d
infixl 8 <^@~

-- | Flipped variant of <tt>~@^&gt;</tt>.
--   
--   This function has the same functionality as function
--   
--   <pre>
--   lens :: (s -&gt; a) -&gt; (s -&gt; b -&gt; t) -&gt; Lens s t a b
--   </pre>
--   
--   Which is defined in <a>lens package</a>. See also section
--   <a>Constructing Lenses</a>.
--   
--   Name of <tt>~@^&gt;</tt> simply says that we apply <a>&lt;$&gt;</a>
--   (<a>fmap</a>) to second (right) arguments and then we apply
--   <tt>~@^&gt;</tt>.
--   
--   Fixity is left associative and set to value 8, which is one less then
--   of function composition (<tt>.</tt>).
--   
--   <i>Since version 0.10.0.0.</i>
(~@@^>) :: Functor f => (a -> b) -> (a -> c -> d) -> (b -> f c) -> a -> f d
infixl 8 ~@@^>

-- | Convenience wrapper for: <tt>\f g -&gt; <a>fmap</a> . f '^</tt>^'
--   <a>fmap</a> . g@.
--   
--   Name of <a>&lt;^@^&gt;</a> simply says that we apply <a>&lt;$&gt;</a>
--   (<a>fmap</a>) to both its arguments and then we apply <a>^@^</a>.
--   
--   Fixity is left associative and set to value 8, which is one less then
--   of function composition (<tt>.</tt>).
--   
--   <i>Since version 0.10.0.0.</i>
(<^@^>) :: (Functor f, Functor g) => (a -> d -> e) -> (a -> b -> c) -> (f c -> g d) -> a -> f b -> g e
infix 8 <^@^>

-- | Flipped variant of <a>&lt;^@^&gt;</a>.
--   
--   Name of <a>&lt;^@@^&gt;</a> simply says that we apply <a>&lt;$&gt;</a>
--   (<a>fmap</a>) to both its arguments and then we apply <a>^@@^</a>.
--   
--   Fixity is set to value 8, which is one less then of function
--   composition (<tt>.</tt>).
--   
--   <i>Since version 0.10.0.0.</i>
(<^@@^>) :: (Functor f, Functor g) => (a -> b -> c) -> (a -> d -> e) -> (f c -> g d) -> a -> f b -> g e
infix 8 <^@@^>

-- | Convenience wrapper for: <tt>\f g -&gt; <a>fmap</a> . f '^</tt>^' g@.
--   
--   This function allows us to define generic lenses from gettern and
--   setter. See section <a>Constructing Lenses</a> for details.
--   
--   Name of <a>&lt;^@^</a> simply says that we apply <a>&lt;$&gt;</a>
--   (<a>fmap</a>) to first (left) arguments and then we apply <a>^@^</a>.
--   
--   Fixity is left associative and set to value 8, which is one less then
--   of function composition (<tt>.</tt>).
--   
--   <i>Since version 0.10.0.0.</i>
(<^@^) :: Functor f => (a -> d -> e) -> (a -> b -> c) -> (c -> f d) -> a -> b -> f e
infix 8 <^@^

-- | Flipped variant of <a>&lt;^@^</a>.
--   
--   This function allows us to define generic lenses from gettern and
--   setter. See section <a>Constructing Lenses</a> for details.
--   
--   Name of <a>^@@^&gt;</a> simply says that we apply <a>&lt;$&gt;</a>
--   (<a>fmap</a>) to second (right) arguments and then we apply
--   <a>^@@^</a>.
--   
--   Fixity is set to value 8, which is one less then of function
--   composition (<tt>.</tt>).
--   
--   <i>Since version 0.10.0.0.</i>
(^@@^>) :: Functor f => (a -> b -> c) -> (a -> d -> e) -> (c -> f d) -> a -> b -> f e
infix 8 ^@@^>

-- | Convenience wrapper for: <tt>\f g -&gt; f '^</tt>^' <a>fmap</a> . g@.
--   
--   Name of <a>^@^&gt;</a> simply says that we apply <a>&lt;$&gt;</a>
--   (<a>fmap</a>) to second (right) arguments and then we apply
--   <a>^@^</a>.
--   
--   Fixity is left associative and set to value 8, which is one less then
--   of function composition (<tt>.</tt>).
--   
--   <i>Since version 0.10.0.0.</i>
(^@^>) :: Functor f => (a -> d -> e) -> (a -> b -> c) -> (f c -> d) -> a -> f b -> e
infix 8 ^@^>

-- | Flipped variant of <a>^@^&gt;</a>.
--   
--   Name of <a>&lt;^@@^</a> simply says that we apply <a>&lt;$&gt;</a>
--   (<a>fmap</a>) to first (left) arguments and then we apply <a>^@@^</a>.
--   
--   Fixity is set to value 8, which is one less then of function
--   composition (<tt>.</tt>).
--   
--   <i>Since version 0.10.0.0.</i>
(<^@@^) :: Functor f => (a -> b -> c) -> (a -> d -> e) -> (f c -> d) -> a -> f b -> e
infix 8 <^@@^

-- | Prefix version of common pattern:
--   
--   <pre>
--   \f -&gt; a `f` b
--   </pre>
--   
--   Where <tt>a</tt> and <tt>b</tt> are fixed parameters. There is also
--   infix version named <a>~$~</a>. This function is defined as:
--   
--   <pre>
--   <a>inbetween</a> a b f = (f $! a) $! b
--   </pre>
--   
--   Based on the above definition one can think of it as a variant
--   function application that deals with two arguments, where in example
--   <a>$</a> only deals with one.
--   
--   <i>Since version 0.11.0.0.</i>
inbetween :: a -> b -> (a -> b -> r) -> r
infix 8 `inbetween`

-- | Infix version of common pattern:
--   
--   <pre>
--   \f -&gt; (f <a>$!</a> a) <a>$!</a> b
--   </pre>
--   
--   Where <tt>a</tt> and <tt>b</tt> are fixed parameters. There is also
--   prefix version named <a>inbetween</a>.
--   
--   <i>Since version 0.11.0.0.</i>
(~$~) :: a -> b -> (a -> b -> r) -> r
infix 8 ~$~

-- | Infix version of common pattern:
--   
--   <pre>
--   \f -&gt; (f <a>$!</a> a) <a>$!</a> b   -- Notice the order of 'a' and 'b'.
--   </pre>
--   
--   <i>Since version 0.11.0.0.</i>
(~$$~) :: b -> a -> (a -> b -> r) -> r
infix 8 ~$$~

-- | Construct a function that encodes idiom:
--   
--   <pre>
--   \f -&gt; f <a>$!</a> a <a>$!</a> b   -- Notice the order of 'b' and 'a'.
--   </pre>
--   
--   Function <a>inbetween</a> can be redefined in terms of <a>withIn</a>
--   as:
--   
--   <pre>
--   a `<a>inbetween</a>` b = <a>withIn</a> <a>$</a> \f -&gt; a `f` b
--   </pre>
--   
--   On one hand you can think of this function as a specialized
--   <tt>id</tt> function and on the other as a function application
--   <a>$</a>. All the following definitions work for lazy variant:
--   
--   <pre>
--   <a>withIn</a> f g = f g
--   <a>withIn</a> = <tt>id</tt>
--   <a>withIn</a> = (<a>$</a>)
--   </pre>
--   
--   For strict variant we use:
--   
--   <pre>
--   <a>withIn</a> f g = f <a>$!</a> g
--   </pre>
--   
--   Usage examples:
--   
--   <pre>
--   newtype Foo a = Foo a
--   
--   inFoo :: ((a -&gt; Foo a) -&gt; (Foo t -&gt; t) -&gt; r) -&gt; r
--   inFoo = <a>withIn</a> <tt>$</tt> \f -&gt;
--       Foo `f` \(Foo a) -&gt; Foo
--   </pre>
--   
--   <pre>
--   data Coords2D = Coords2D {_x :: Int, _y :: Int}
--   
--   inX :: ((Int -&gt; Coords2D -&gt; Coords2D) -&gt; (Coords2D -&gt; Int) -&gt; r) -&gt; r
--   inX = <a>withIn</a> <tt>$</tt> \f -&gt;
--       (\b s -&gt; s{_x = b}) `f` _x
--   </pre>
--   
--   <i>Since version 0.11.0.0.</i>
withIn :: ((a -> b -> r) -> r) -> (a -> b -> r) -> r

-- | Construct a function that encodes idiom:
--   
--   <pre>
--   \f -&gt; b `f` a     -- Notice the order of 'b' and 'a'.
--   </pre>
--   
--   Function <a>~$$~</a> can be redefined in terms of <a>withReIn</a> as:
--   
--   <pre>
--   b <a>~$$~</a> a = <a>withReIn</a> <tt>$</tt> \f -&gt; b `f` a
--   </pre>
--   
--   As <a>withIn</a>, but the function is flipped before applied. All of
--   the following definitions work for lazy variant:
--   
--   <pre>
--   <a>withReIn</a> f g = f (<a>flip</a> g)
--   <a>withReIn</a> = (<a>.</a> <a>flip</a>)
--   </pre>
--   
--   For strict variant we can use:
--   
--   <pre>
--   <a>withReIn</a> f g = f <a>$!</a> \b a -&gt; <a>inbetween</a> a b g
--   <a>withReIn</a> f g = f <a>$!</a> \b a -&gt; (a <a>~$~</a> b) g
--   <a>withReIn</a> f g = f <a>$!</a> \b a -&gt; (b <a>~$$~</a> a) g
--   <a>withReIn</a> f g = f <a>$!</a> \b a -&gt; g <a>$!</a> a <a>$!</a> b
--   <a>withReIn</a> f g = <a>withIn</a> f (\b a -&gt; g <a>$!</a> a <a>$!</a> b)
--   <a>withReIn</a> f g = <a>withIn</a> f $! <a>flip</a> $! g   -- With strict <a>flip</a>.
--   </pre>
--   
--   Usage examples:
--   
--   <pre>
--   newtype Foo a = Foo a
--   
--   inFoo :: ((a -&gt; Foo a) -&gt; (Foo t -&gt; t) -&gt; r) -&gt; r
--   inFoo = <a>withReIn</a> <tt>$</tt> \f -&gt;
--       (\(Foo a) -&gt; Foo) `f` Foo
--   </pre>
--   
--   <pre>
--   data Coords2D = Coords2D {_x :: Int, _y :: Int}
--   
--   inX :: ((Int -&gt; Coords2D -&gt; Coords2D) -&gt; (Coords2D -&gt; Int) -&gt; r) -&gt; r
--   inX = <a>withReIn</a> <tt>$</tt> \f -&gt;
--       _x `f` \b s -&gt; s{_x = b}
--   </pre>
--   
--   <i>Since version 0.11.0.0.</i>
withReIn :: ((b -> a -> r) -> r) -> (a -> b -> r) -> r

-- | Family of types that can construct isomorphism between types.
--   
--   <i>Since version 0.11.0.0.</i>
type PreIso r s t a b = ((b -> t) -> (s -> a) -> r) -> r

-- | A simple <a>PreIso</a>.
--   
--   <i>Since version 0.11.0.0.</i>
type PreIso' r s a = PreIso r s s a a

-- | Construct a <a>PreIso</a>; this function similar to <i>Iso</i>
--   constructor function from <i>lens</i> package:
--   
--   <pre>
--   iso :: (s -&gt; a) -&gt; (b -&gt; t) -&gt; Iso s t a b
--   </pre>
--   
--   Usage example:
--   
--   <pre>
--   data Foo a = Foo a
--   
--   preFoo :: <a>PreIso</a> r (Foo a) (Foo b) a b
--   preFoo = Foo `<a>preIso</a>` \(Foo a) -&gt; a
--   </pre>
preIso :: (s -> a) -> (b -> t) -> PreIso r s t a b

-- | Flipped variant of <a>preIso</a>.
--   
--   Usage example:
--   
--   <pre>
--   data Foo a = Foo {_getFoo :: a}
--   
--   preFoo :: <a>PreIso</a> r (Foo a) (Foo b) a b
--   preFoo = _getFoo `<a>preIso'</a>` Foo
--   </pre>
preIso' :: (b -> t) -> (s -> a) -> PreIso r s t a b

-- | We can also view <a>PreLens</a> as a special kind of <a>PreIso</a>:
--   
--   <pre>
--   <a>PreLens</a> r s t a b = <a>PreIso</a> r s (s -&gt; t) a b
--   </pre>
--   
--   <i>Since version 0.11.0.0.</i>
type PreLens r s t a b = ((b -> s -> t) -> (s -> a) -> r) -> r

-- | A simple <a>PreLens</a>, where we can not change the type of the
--   information we are focusing on. As a consequence neither the type of
--   the container data type can be changed.
--   
--   <i>Since version 0.11.0.0.</i>
type PreLens' r s a = PreLens r s s a a

-- | Construct a <a>PreLens</a>; this function is similar to <i>Lens</i>
--   constructor function from <i>lens</i> package:
--   
--   <pre>
--   lens :: (s -&gt; b -&gt; t) -&gt; (s -&gt; a) -&gt; Lens' s t a b
--   </pre>
--   
--   Usage example:
--   
--   <pre>
--   data Coords2D = Coords2D {_x :: Int, _y :: Int}
--   
--   preX :: PreLens' r Coords2D Int
--   preX = (\s b -&gt; s{_x = b}) `<a>preLens</a>` _x
--   </pre>
preLens :: (s -> b -> t) -> (s -> a) -> PreLens r s t a b

-- | Flipped version of <a>preLens</a> that takes getter first and setter
--   second.
--   
--   <pre>
--   data Coords2D = Coords2D {_x :: Int, _y :: Int}
--   
--   preX :: PreLens' r Coords2D Int
--   preX = _x `<a>preLens'</a>` \s b -&gt; s{_x = b}
--   </pre>
preLens' :: (s -> a) -> (s -> b -> t) -> PreLens r s t a b

-- | Convert <a>PreIso</a> in to <a>PreLens</a> by injecting const to a
--   setter function.
--   
--   <pre>
--   <a>preIsoToPreLens</a> aPreIso f = aPreIso <tt>$</tt> \fbt fsa -&gt; <a>const</a> fbt `f` fsa
--   </pre>
preIsoToPreLens :: PreIso r s t a b -> PreLens r s t a b

-- | Construct a <tt>Lens</tt> out of a <a>PreLens</a>.
--   
--   <pre>
--   data Coords2D = Coords2D {_x :: Int, _y :: Int}
--   
--   preX :: PreLens' r Coords2D Int
--   preX = _x `<a>preLens'</a>` \s b -&gt; s{_x = b}
--   
--   x :: Lens' Coords2D Int
--   x = <a>le</a> preX
--   </pre>
le :: Functor f => PreLens ((a -> f b) -> s -> f t) s t a b -> (a -> f b) -> s -> f t

-- | We can also get <a>PrePrism</a> by specializing <a>PreIso</a>:
--   
--   <pre>
--   <a>PrePrism</a> r s t a b = <a>PreIso</a> r s t (<a>Either</a> t a) b
--   </pre>
--   
--   This fact is not surprising, since <i>Prisms</i> are actually a
--   special case of isomorphism between two types.
--   
--   Let's have a type <tt>s</tt>, and we want to extract specific
--   information out of it, but that information may not be there. Because
--   of the fact that the type <tt>s</tt> can be a sum type. Imagine e.g.
--   standard <tt>Maybe</tt> data type:
--   
--   <pre>
--   <tt>Maybe</tt> a = <a>Nothing</a> | <a>Just</a> a
--   </pre>
--   
--   How do we create something that can extrat that information from a sum
--   type, and if necessary, also reconstructs that sum type. The answer is
--   <i>Prism</i>, which is defined as an isomorphism between that type
--   <tt>s</tt> and <tt><a>Either</a> t a</tt> where <tt>a</tt> is the
--   information we want to extract and <tt>t</tt> is the rest that we
--   don't care about.
--   
--   You may have noticed, that definition of <a>PrePrism</a> contains some
--   type variables that aren't mentioned in the above definition. The
--   reason for this is that, as with <i>Lenses</i> we may want to extract
--   value of type <tt>a</tt>, but when constructing new data type we may
--   want to change the type of that value in to <tt>b</tt> and therefore
--   type <tt>s</tt> may not fit, which is the reason why we have type
--   <tt>t</tt> in there. Once again we can ilustrate this with
--   <tt>Maybe</tt>. Lets say that we have a value of <tt>s =
--   <tt>Maybe</tt> a</tt>, but if we change the type of <tt>a</tt> in to
--   <tt>b</tt>, and try to create <tt>Maybe</tt> again, then it would have
--   type <tt><tt>Maybe</tt> b = t</tt>.
--   
--   <i>Since version 0.11.0.0.</i>
type PrePrism r s t a b = ((b -> t) -> (s -> Either t a) -> r) -> r

-- | A simple <a>PrePrism</a>, where we can not change the type of the
--   information we are focusing on. As a consequence neither the type of
--   the container data type can be changed.
--   
--   If we define <a>PrePrism'</a> in terms of <a>PreIso'</a> then we have
--   even better ilustration of <i>Prism</i> concept in terms of
--   isomorphism:
--   
--   <pre>
--   <a>PrePrism'</a> r s a = <a>PreIso'</a> r s (<a>Either</a> t a)
--   </pre>
--   
--   <i>Since version 0.11.0.0.</i>
type PrePrism' r s a = PrePrism r s s a a

-- | Constract a <a>PrePrism</a>; this function is similar to <i>Prism</i>
--   constructor function from <i>lens</i> package:
--   
--   <pre>
--   prism :: (b -&gt; t) -&gt; (s -&gt; <a>Either</a> t a) -&gt; Prism s t a b
--   </pre>
--   
--   Usage example:
--   
--   <pre>
--   {-# LANGUAGE LambdaCase #-}
--   data Sum a b = A a | B b
--   
--   preA :: <a>PrePrism</a> r (Sum a c) (Sum b c) a b
--   preA = <a>prePrism</a> A <tt>$</tt> \case
--       A a -&gt; <a>Right</a> a
--       B b -&gt; <a>Left</a> (B b)
--   </pre>
prePrism :: (b -> t) -> (s -> Either t a) -> PrePrism r s t a b

-- | Simplified construction of <a>PrePrism</a>, which can be used in
--   following situations:
--   
--   <ul>
--   <li>Constructing <i>Prism</i> for types isomorphic to <a>Maybe</a>
--   or</li>
--   <li>when using <a>cast</a> operation, or similar, which either returns
--   what you want or <a>Nothing</a>.</li>
--   </ul>
--   
--   Alternative type signature of this function is also:
--   
--   <pre>
--   <a>prePrism'</a> :: <a>PreIso</a> r s s (<a>Maybe</a> a) b -&gt; <a>PrePrism</a> r s s a b
--   </pre>
prePrism' :: (b -> s) -> (s -> Maybe a) -> PrePrism r s s a b


-- | Implementation of lazy <a>between</a> combinator and its variations.
--   For introductory documentation see module <a>Data.Function.Between</a>
--   and for strict versions import <a>Data.Function.Between.Strict</a>
--   module.
--   
--   Prior to version 0.10.0.0 functions defined in this module were
--   directly in <a>Data.Function.Between</a>.
--   
--   <i>Module available since version 0.10.0.0.</i>
module Data.Function.Between.Lazy

-- | Core combinator of this module and we build others on top of. It also
--   has an infix form <a>~@~</a> and flipped infix form <a>~@@~</a>.
--   
--   This function Defined as:
--   
--   <pre>
--   <a>between</a> f g -&gt; (f .) . (. g)
--   </pre>
between :: (c -> d) -> (a -> b) -> (b -> c) -> a -> d

-- | Infix variant of <a>between</a>.
--   
--   Fixity is left associative and set to value 8, which is one less then
--   fixity of function composition (<a>.</a>).
(~@~) :: (c -> d) -> (a -> b) -> (b -> c) -> a -> d
infixl 8 ~@~

-- | Flipped variant of <a>~@~</a>, i.e. flipped infix variant of
--   <a>between</a>.
--   
--   Fixity is right associative and set to value 8, which is one less then
--   fixity of function composition (<a>.</a>).
(~@@~) :: (a -> b) -> (c -> d) -> (b -> c) -> a -> d
infixr 8 ~@@~

-- | As <a>~@~</a>, but first function is also parametrised with
--   <tt>a</tt>, hence the name <a>^@~</a>. Character <tt>^</tt> indicates
--   which argument is parametrised with additional argument.
--   
--   This function is defined as:
--   
--   <pre>
--   (f <a>^@~</a> g) h a -&gt; (f a <a>~@~</a> g) h a
--   </pre>
--   
--   Fixity is left associative and set to value 8, which is one less then
--   fixity of function composition (<a>.</a>).
(^@~) :: (a -> c -> d) -> (a -> b) -> (b -> c) -> a -> d
infixl 8 ^@~

-- | Flipped variant of <a>^@~</a>.
--   
--   Fixity is right associative and set to value 8, which is one less then
--   fixity of function composition (<a>.</a>).
(~@@^) :: (a -> b) -> (a -> c -> d) -> (b -> c) -> a -> d
infixr 8 ~@@^

-- | Pass additional argument to first two function arguments.
--   
--   This function is defined as:
--   
--   <pre>
--   (f <a>^@^</a> g) h a b -&gt; (f a <a>~@~</a> g a) h b
--   </pre>
--   
--   See also <a>^@~</a> to note the difference, most importantly that
--   <a>^@~</a> passes the same argument to all its functional arguments.
--   Function <a>^@~</a> can be defined in terms of this one as:
--   
--   <pre>
--   (f <a>^@~</a> g) h a = (f <a>^@^</a> <a>const</a> g) h a a
--   </pre>
--   
--   We can do it also the other way around and define <a>^@^</a> using
--   <a>^@~</a>:
--   
--   <pre>
--   f <a>^@^</a> g =
--       <a>curry</a> . (f . <a>snd</a> <a>^@~</a> <a>uncurry</a> g)
--   </pre>
--   
--   Fixity is set to value 8, which is one less then of function
--   composition (<a>.</a>).
(^@^) :: (a -> d -> e) -> (a -> b -> c) -> (c -> d) -> a -> b -> e
infix 8 ^@^

-- | Flipped variant of <a>^@^</a>.
--   
--   Fixity is set to value 8, which is one less then of function
--   composition (<a>.</a>).
(^@@^) :: (a -> b -> c) -> (a -> d -> e) -> (c -> d) -> a -> b -> e
infix 8 ^@@^

-- | Apply function <tt>g</tt> to each argument of binary function and
--   <tt>f</tt> to its result. In suffix "2l" the number is equal to arity
--   of the function it accepts as a third argument and character "l" is
--   for "left associative".
--   
--   <pre>
--   <a>between2l</a> f g = (f <a>~@~</a> g) <a>~@~</a> g
--   </pre>
--   
--   Interesting observation:
--   
--   <pre>
--   (\f g -&gt; <a>between2l</a> <a>id</a> g f) === <a>on</a>
--   </pre>
between2l :: (c -> d) -> (a -> b) -> (b -> b -> c) -> a -> a -> d

-- | Apply function <tt>g</tt> to each argument of ternary function and
--   <tt>f</tt> to its result. In suffix "3l" the number is equal to arity
--   of the function it accepts as a third argument and character "l" is
--   for "left associative".
--   
--   This function is defined as:
--   
--   <pre>
--   <a>between3l</a> f g = ((f <a>~@~</a> g) <a>~@~</a> g) <a>~@~</a> g
--   </pre>
--   
--   Alternatively it can be defined using <a>between2l</a>:
--   
--   <pre>
--   <a>between3l</a> f g = <a>between2l</a> f g <a>~@~</a> g
--   </pre>
between3l :: (c -> d) -> (a -> b) -> (b -> b -> b -> c) -> a -> a -> a -> d

-- | Convenience wrapper for:
--   
--   <pre>
--   \f g -&gt; <a>fmap</a> f <a>~@~</a> <a>fmap</a> g
--   </pre>
--   
--   Name of <a>&lt;~@~&gt;</a> simply says that we apply <a>&lt;$&gt;</a>
--   (<a>fmap</a>) to both its arguments and then we apply <a>~@~</a>.
--   
--   Fixity is left associative and set to value 8, which is one less then
--   of function composition (<a>.</a>).
(<~@~>) :: (Functor f, Functor g) => (c -> d) -> (a -> b) -> (f b -> g c) -> f a -> g d
infix 8 <~@~>

-- | Flipped variant of <a>&lt;~@~&gt;</a>.
--   
--   Name of <a>&lt;~@@~&gt;</a> simply says that we apply <a>&lt;$&gt;</a>
--   (<a>fmap</a>) to both its arguments and then we apply <a>~@@~</a>.
--   
--   Fixity is set to value 8, which is one less then of function
--   composition (<a>.</a>).
(<~@@~>) :: (Functor f, Functor g) => (a -> b) -> (c -> d) -> (f b -> g c) -> f a -> g d
infix 8 <~@@~>

-- | Apply <a>fmap</a> to first argument of <a>~@~</a>. Dual to
--   <a>~@~&gt;</a> which applies <a>fmap</a> to second argument.
--   
--   Defined as:
--   
--   <pre>
--   f <a>&lt;~@~</a> g = <a>fmap</a> f <a>~@~</a> g
--   </pre>
--   
--   This function allows us to define lenses mostly for pair of functions
--   that form an isomorphism. See section <a>Constructing Lenses</a> for
--   details.
--   
--   Name of <a>&lt;~@~</a> simply says that we apply <a>&lt;$&gt;</a>
--   (<a>fmap</a>) to first (left) argument and then we apply <a>~@~</a>.
--   
--   Fixity is left associative and set to value 8, which is one less then
--   of function composition (<a>.</a>).
(<~@~) :: Functor f => (c -> d) -> (a -> b) -> (b -> f c) -> a -> f d
infixl 8 <~@~

-- | Flipped variant of <a>&lt;~@~</a>.
--   
--   This function allows us to define lenses mostly for pair of functions
--   that form an isomorphism. See section <a>Constructing Lenses</a> for
--   details.
--   
--   Name of <a>~@@~&gt;</a> simply says that we apply <a>&lt;$&gt;</a>
--   (<a>fmap</a>) to second (right) argument and then we apply
--   <a>~@@~</a>.
--   
--   Fixity is right associative and set to value 8, which is one less then
--   fixity of function composition (<a>.</a>).
(~@@~>) :: Functor f => (a -> b) -> (c -> d) -> (b -> f c) -> a -> f d
infixr 8 ~@@~>

-- | Apply <a>fmap</a> to second argument of <a>~@~</a>. Dual to
--   <a>&lt;~@~</a> which applies <a>fmap</a> to first argument.
--   
--   Defined as:
--   
--   <pre>
--   f <a>~@~&gt;</a> g -&gt; f <a>~@~</a> <a>fmap</a> g
--   </pre>
--   
--   Name of <a>~@~&gt;</a> simply says that we apply <a>&lt;$&gt;</a>
--   (<a>fmap</a>) to second (right) argument and then we apply <a>~@~</a>.
--   
--   Fixity is right associative and set to value 8, which is one less then
--   of function composition (<a>.</a>).
(~@~>) :: Functor f => (c -> d) -> (a -> b) -> (f b -> c) -> f a -> d
infixl 8 ~@~>

-- | Flipped variant of <a>~@~&gt;</a>.
--   
--   Name of <a>&lt;~@@~</a> simply says that we apply <a>&lt;$&gt;</a>
--   (<a>fmap</a>) to first (left) argument and then we apply <a>~@@~</a>.
--   
--   Fixity is left associative and set to value 8, which is one less then
--   fixity of function composition (<a>.</a>).
(<~@@~) :: Functor f => (a -> b) -> (c -> d) -> (f b -> c) -> f a -> d
infixr 8 <~@@~

-- | Convenience wrapper for: <tt>\f g -&gt; <a>fmap</a> . f '^</tt>~' g@.
--   
--   This function has the same functionality as function
--   
--   <pre>
--   lens :: (s -&gt; a) -&gt; (s -&gt; b -&gt; t) -&gt; Lens s t a b
--   </pre>
--   
--   Which is defined in <a>lens package</a>. Only difference is that
--   arguments of <a>&lt;^@~</a> are flipped. See also section
--   <a>Constructing Lenses</a>.
--   
--   Name of <a>&lt;^@~</a> simply says that we apply <a>&lt;$&gt;</a>
--   (<a>fmap</a>) to first (left) arguments and then we apply <a>^@~</a>.
--   
--   Fixity is left associative and set to value 8, which is one less then
--   of function composition (<a>.</a>).
(<^@~) :: Functor f => (a -> c -> d) -> (a -> b) -> (b -> f c) -> a -> f d
infixl 8 <^@~

-- | Flipped variant of <tt>~@^&gt;</tt>.
--   
--   This function has the same functionality as function
--   
--   <pre>
--   lens :: (s -&gt; a) -&gt; (s -&gt; b -&gt; t) -&gt; Lens s t a b
--   </pre>
--   
--   Which is defined in <a>lens package</a>. See also section
--   <a>Constructing Lenses</a>.
--   
--   Name of <tt>~@^&gt;</tt> simply says that we apply <a>&lt;$&gt;</a>
--   (<a>fmap</a>) to second (right) arguments and then we apply
--   <tt>~@^&gt;</tt>.
--   
--   Fixity is left associative and set to value 8, which is one less then
--   of function composition (<a>.</a>).
(~@@^>) :: Functor f => (a -> b) -> (a -> c -> d) -> (b -> f c) -> a -> f d
infixl 8 ~@@^>

-- | Convenience wrapper for: <tt>\f g -&gt; <a>fmap</a> . f '^</tt>^'
--   <a>fmap</a> . g@.
--   
--   Name of <a>&lt;^@^&gt;</a> simply says that we apply <a>&lt;$&gt;</a>
--   (<a>fmap</a>) to both its arguments and then we apply <a>^@^</a>.
--   
--   Fixity is left associative and set to value 8, which is one less then
--   of function composition (<a>.</a>).
(<^@^>) :: (Functor f, Functor g) => (a -> d -> e) -> (a -> b -> c) -> (f c -> g d) -> a -> f b -> g e
infix 8 <^@^>

-- | Flipped variant of <a>&lt;^@^&gt;</a>.
--   
--   Name of <a>&lt;^@@^&gt;</a> simply says that we apply <a>&lt;$&gt;</a>
--   (<a>fmap</a>) to both its arguments and then we apply <a>^@@^</a>.
--   
--   Fixity is set to value 8, which is one less then of function
--   composition (<a>.</a>).
(<^@@^>) :: (Functor f, Functor g) => (a -> b -> c) -> (a -> d -> e) -> (f c -> g d) -> a -> f b -> g e
infix 8 <^@@^>

-- | Convenience wrapper for: <tt>\f g -&gt; <a>fmap</a> . f '^</tt>^' g@.
--   
--   This function allows us to define generic lenses from gettern and
--   setter. See section <a>Constructing Lenses</a> for details.
--   
--   Name of <a>&lt;^@^</a> simply says that we apply <a>&lt;$&gt;</a>
--   (<a>fmap</a>) to first (left) arguments and then we apply <a>^@^</a>.
--   
--   Fixity is left associative and set to value 8, which is one less then
--   of function composition (<a>.</a>).
(<^@^) :: Functor f => (a -> d -> e) -> (a -> b -> c) -> (c -> f d) -> a -> b -> f e
infix 8 <^@^

-- | Flipped variant of <a>&lt;^@^</a>.
--   
--   This function allows us to define generic lenses from gettern and
--   setter. See section <a>Constructing Lenses</a> for details.
--   
--   Name of <a>^@@^&gt;</a> simply says that we apply <a>&lt;$&gt;</a>
--   (<a>fmap</a>) to second (right) arguments and then we apply
--   <a>^@@^</a>.
--   
--   Fixity is set to value 8, which is one less then of function
--   composition (<a>.</a>).
(^@@^>) :: Functor f => (a -> b -> c) -> (a -> d -> e) -> (c -> f d) -> a -> b -> f e
infix 8 ^@@^>

-- | Convenience wrapper for: <tt>\f g -&gt; f '^</tt>^' <a>fmap</a> . g@.
--   
--   Name of <a>^@^&gt;</a> simply says that we apply <a>&lt;$&gt;</a>
--   (<a>fmap</a>) to second (right) arguments and then we apply
--   <a>^@^</a>.
--   
--   Fixity is left associative and set to value 8, which is one less then
--   of function composition (<a>.</a>).
(^@^>) :: Functor f => (a -> d -> e) -> (a -> b -> c) -> (f c -> d) -> a -> f b -> e
infix 8 ^@^>

-- | Flipped variant of <a>^@^&gt;</a>.
--   
--   Name of <a>&lt;^@@^</a> simply says that we apply <a>&lt;$&gt;</a>
--   (<a>fmap</a>) to first (left) arguments and then we apply <a>^@@^</a>.
--   
--   Fixity is set to value 8, which is one less then of function
--   composition (<a>.</a>).
(<^@@^) :: Functor f => (a -> b -> c) -> (a -> d -> e) -> (f c -> d) -> a -> f b -> e
infix 8 <^@@^

-- | Prefix version of common pattern:
--   
--   <pre>
--   \f -&gt; a `f` b
--   </pre>
--   
--   Where <tt>a</tt> and <tt>b</tt> are fixed parameters. There is also
--   infix version named <a>~$~</a>. This function is defined as:
--   
--   <pre>
--   <a>inbetween</a> a b f = f a b
--   </pre>
--   
--   Based on the above definition one can think of it as a variant
--   function application that deals with two arguments, where in example
--   <a>$</a> only deals with one.
--   
--   <i>Since version 0.11.0.0.</i>
inbetween :: a -> b -> (a -> b -> r) -> r
infix 8 `inbetween`

-- | Infix version of common pattern:
--   
--   <pre>
--   \f -&gt; a `f` b
--   </pre>
--   
--   Where <tt>a</tt> and <tt>b</tt> are fixed parameters. There is also
--   prefix version named <a>inbetween</a>.
--   
--   <i>Since version 0.11.0.0.</i>
(~$~) :: a -> b -> (a -> b -> r) -> r
infix 8 ~$~

-- | Infix version of common pattern:
--   
--   <pre>
--   \f -&gt; a `f` b     -- Notice the order of 'a' and 'b'.
--   </pre>
--   
--   <i>Since version 0.11.0.0.</i>
(~$$~) :: b -> a -> (a -> b -> r) -> r
infix 8 ~$$~

-- | Construct a function that encodes idiom:
--   
--   <pre>
--   \f -&gt; a `f` b     -- Notice the order of 'b' and 'a'.
--   </pre>
--   
--   Function <a>inbetween</a> can be redefined in terms of <a>withIn</a>
--   as:
--   
--   <pre>
--   a `<a>inbetween</a>` b = <a>withIn</a> <a>$</a> \f -&gt; a `f` b
--   </pre>
--   
--   On one hand you can think of this function as a specialized <a>id</a>
--   function and on the other as a function application <a>$</a>. All the
--   following definitions work:
--   
--   <pre>
--   <a>withIn</a> f g = f g
--   <a>withIn</a> = <a>id</a>
--   <a>withIn</a> = (<a>$</a>)
--   </pre>
--   
--   Usage examples:
--   
--   <pre>
--   newtype Foo a = Foo a
--   
--   inFoo :: ((a -&gt; Foo a) -&gt; (Foo t -&gt; t) -&gt; r) -&gt; r
--   inFoo = <a>withIn</a> <a>$</a> \f -&gt;
--       Foo `f` \(Foo a) -&gt; Foo
--   </pre>
--   
--   <pre>
--   data Coords2D = Coords2D {_x :: Int, _y :: Int}
--   
--   inX :: ((Int -&gt; Coords2D -&gt; Coords2D) -&gt; (Coords2D -&gt; Int) -&gt; r) -&gt; r
--   inX = <a>withIn</a> <a>$</a> \f -&gt;
--       (\b s -&gt; s{_x = b}) `f` _x
--   </pre>
--   
--   <i>Since version 0.11.0.0.</i>
withIn :: ((a -> b -> r) -> r) -> (a -> b -> r) -> r

-- | Construct a function that encodes idiom:
--   
--   <pre>
--   \f -&gt; b `f` a     -- Notice the order of 'b' and 'a'.
--   </pre>
--   
--   Function <a>~$$~</a> can be redefined in terms of <a>withReIn</a> as:
--   
--   <pre>
--   b <a>~$$~</a> a = <a>withReIn</a> <a>$</a> \f -&gt; b `f` a
--   </pre>
--   
--   As <a>withIn</a>, but the function is flipped before applied. All of
--   the following definitions work:
--   
--   <pre>
--   <a>withReIn</a> f g = f (<a>flip</a> g)
--   <a>withReIn</a> = (<a>.</a> <a>flip</a>)
--   </pre>
--   
--   Usage examples:
--   
--   <pre>
--   newtype Foo a = Foo a
--   
--   inFoo :: ((a -&gt; Foo a) -&gt; (Foo t -&gt; t) -&gt; r) -&gt; r
--   inFoo = <a>withReIn</a> <a>$</a> \f -&gt;
--       (\(Foo a) -&gt; Foo) `f` Foo
--   </pre>
--   
--   <pre>
--   data Coords2D = Coords2D {_x :: Int, _y :: Int}
--   
--   inX :: ((Int -&gt; Coords2D -&gt; Coords2D) -&gt; (Coords2D -&gt; Int) -&gt; r) -&gt; r
--   inX = <a>withReIn</a> <a>$</a> \f -&gt;
--       _x `f` \b s -&gt; s{_x = b}
--   </pre>
--   
--   <i>Since version 0.11.0.0.</i>
withReIn :: ((b -> a -> r) -> r) -> (a -> b -> r) -> r

-- | Family of types that can construct isomorphism between types.
--   
--   <i>Since version 0.11.0.0.</i>
type PreIso r s t a b = ((b -> t) -> (s -> a) -> r) -> r

-- | A simple <a>PreIso</a>.
--   
--   <i>Since version 0.11.0.0.</i>
type PreIso' r s a = PreIso r s s a a

-- | Construct a <a>PreIso</a>; this function similar to <i>Iso</i>
--   constructor function from <i>lens</i> package:
--   
--   <pre>
--   iso :: (s -&gt; a) -&gt; (b -&gt; t) -&gt; Iso s t a b
--   </pre>
--   
--   Usage example:
--   
--   <pre>
--   data Foo a = Foo a
--   
--   preFoo :: <a>PreIso</a> r (Foo a) (Foo b) a b
--   preFoo = Foo `<a>preIso</a>` \(Foo a) -&gt; a
--   </pre>
preIso :: (s -> a) -> (b -> t) -> PreIso r s t a b

-- | Flipped variant of <a>preIso</a>.
--   
--   Usage example:
--   
--   <pre>
--   data Foo a = Foo {_getFoo :: a}
--   
--   preFoo :: <a>PreIso</a> r (Foo a) (Foo b) a b
--   preFoo = _getFoo `<a>preIso'</a>` Foo
--   </pre>
preIso' :: (b -> t) -> (s -> a) -> PreIso r s t a b

-- | We can also view <a>PreLens</a> as a special kind of <a>PreIso</a>:
--   
--   <pre>
--   <a>PreLens</a> r s t a b = <a>PreIso</a> r s (s -&gt; t) a b
--   </pre>
--   
--   <i>Since version 0.11.0.0.</i>
type PreLens r s t a b = ((b -> s -> t) -> (s -> a) -> r) -> r

-- | A simple <a>PreLens</a>, where we can not change the type of the
--   information we are focusing on. As a consequence neither the type of
--   the container data type can be changed.
--   
--   <i>Since version 0.11.0.0.</i>
type PreLens' r s a = PreLens r s s a a

-- | Construct a <a>PreLens</a>; this function is similar to <i>Lens</i>
--   constructor function from <i>lens</i> package:
--   
--   <pre>
--   lens :: (s -&gt; b -&gt; t) -&gt; (s -&gt; a) -&gt; Lens' s t a b
--   </pre>
--   
--   Usage example:
--   
--   <pre>
--   data Coords2D = Coords2D {_x :: Int, _y :: Int}
--   
--   preX :: PreLens' r Coords2D Int
--   preX = (\s b -&gt; s{_x = b}) `<a>preLens</a>` _x
--   </pre>
preLens :: (s -> b -> t) -> (s -> a) -> PreLens r s t a b

-- | Flipped version of <a>preLens</a> that takes getter first and setter
--   second.
--   
--   <pre>
--   data Coords2D = Coords2D {_x :: Int, _y :: Int}
--   
--   preX :: PreLens' r Coords2D Int
--   preX = _x `<a>preLens'</a>` \s b -&gt; s{_x = b}
--   </pre>
preLens' :: (s -> a) -> (s -> b -> t) -> PreLens r s t a b

-- | Convert <a>PreIso</a> in to <a>PreLens</a> by injecting const to a
--   setter function.
--   
--   <pre>
--   <a>preIsoToPreLens</a> aPreIso f = aPreIso <a>$</a> \fbt fsa -&gt; <a>const</a> fbt `f` fsa
--   </pre>
preIsoToPreLens :: PreIso r s t a b -> PreLens r s t a b

-- | Construct a <tt>Lens</tt> out of a <a>PreLens</a>.
--   
--   <pre>
--   data Coords2D = Coords2D {_x :: Int, _y :: Int}
--   
--   preX :: PreLens' r Coords2D Int
--   preX = _x `<a>preLens'</a>` \s b -&gt; s{_x = b}
--   
--   x :: Lens' Coords2D Int
--   x = <a>le</a> preX
--   </pre>
le :: Functor f => PreLens ((a -> f b) -> s -> f t) s t a b -> (a -> f b) -> s -> f t

-- | We can also get <a>PrePrism</a> by specializing <a>PreIso</a>:
--   
--   <pre>
--   <a>PrePrism</a> r s t a b = <a>PreIso</a> r s t (<a>Either</a> t a) b
--   </pre>
--   
--   This fact is not surprising, since <i>Prisms</i> are actually a
--   special case of isomorphism between two types.
--   
--   Let's have a type <tt>s</tt>, and we want to extract specific
--   information out of it, but that information may not be there. Because
--   of the fact that the type <tt>s</tt> can be a sum type. Imagine e.g.
--   standard <tt>Maybe</tt> data type:
--   
--   <pre>
--   <tt>Maybe</tt> a = <a>Nothing</a> | <a>Just</a> a
--   </pre>
--   
--   How do we create something that can extrat that information from a sum
--   type, and if necessary, also reconstructs that sum type. The answer is
--   <i>Prism</i>, which is defined as an isomorphism between that type
--   <tt>s</tt> and <tt><a>Either</a> t a</tt> where <tt>a</tt> is the
--   information we want to extract and <tt>t</tt> is the rest that we
--   don't care about.
--   
--   You may have noticed, that definition of <a>PrePrism</a> contains some
--   type variables that aren't mentioned in the above definition. The
--   reason for this is that, as with <i>Lenses</i> we may want to extract
--   value of type <tt>a</tt>, but when constructing new data type we may
--   want to change the type of that value in to <tt>b</tt> and therefore
--   type <tt>s</tt> may not fit, which is the reason why we have type
--   <tt>t</tt> in there. Once again we can ilustrate this with
--   <tt>Maybe</tt>. Lets say that we have a value of <tt>s =
--   <tt>Maybe</tt> a</tt>, but if we change the type of <tt>a</tt> in to
--   <tt>b</tt>, and try to create <tt>Maybe</tt> again, then it would have
--   type <tt><tt>Maybe</tt> b = t</tt>.
--   
--   <i>Since version 0.11.0.0.</i>
type PrePrism r s t a b = ((b -> t) -> (s -> Either t a) -> r) -> r

-- | A simple <a>PrePrism</a>, where we can not change the type of the
--   information we are focusing on. As a consequence neither the type of
--   the container data type can be changed.
--   
--   If we define <a>PrePrism'</a> in terms of <a>PreIso'</a> then we have
--   even better ilustration of <i>Prism</i> concept in terms of
--   isomorphism:
--   
--   <pre>
--   <a>PrePrism'</a> r s a = <a>PreIso'</a> r s (<a>Either</a> t a)
--   </pre>
--   
--   <i>Since version 0.11.0.0.</i>
type PrePrism' r s a = PrePrism r s s a a

-- | Constract a <a>PrePrism</a>; this function is similar to <i>Prism</i>
--   constructor function from <i>lens</i> package:
--   
--   <pre>
--   prism :: (b -&gt; t) -&gt; (s -&gt; <a>Either</a> t a) -&gt; Prism s t a b
--   </pre>
--   
--   Usage example:
--   
--   <pre>
--   {-# LANGUAGE LambdaCase #-}
--   data Sum a b = A a | B b
--   
--   preA :: <a>PrePrism</a> r (Sum a c) (Sum b c) a b
--   preA = <a>prePrism</a> A <a>$</a> \case
--       A a -&gt; <a>Right</a> a
--       B b -&gt; <a>Left</a> (B b)
--   </pre>
prePrism :: (b -> t) -> (s -> Either t a) -> PrePrism r s t a b

-- | Simplified construction of <a>PrePrism</a>, which can be used in
--   following situations:
--   
--   <ul>
--   <li>Constructing <i>Prism</i> for types isomorphic to <a>Maybe</a>
--   or</li>
--   <li>when using <a>cast</a> operation, or similar, which either returns
--   what you want or <a>Nothing</a>.</li>
--   </ul>
--   
--   Alternative type signature of this function is also:
--   
--   <pre>
--   <a>prePrism'</a> :: <a>PreIso</a> r s s (<a>Maybe</a> a) b -&gt; <a>PrePrism</a> r s s a b
--   </pre>
prePrism' :: (b -> s) -> (s -> Maybe a) -> PrePrism r s s a b


-- | During development it is common occurrence to modify deeply nested
--   structures. One of the best known libraries for this purpose is
--   <a>lens</a>, but it's quite overkill for some purposes.
--   
--   This library describes simple and composable combinators that are
--   built on top of few very basic concepts. First one is:
--   
--   <pre>
--   \h -&gt; f . h . g
--   </pre>
--   
--   Where <tt>f</tt> and <tt>g</tt> are fixed and <tt>h</tt> is a free
--   variable. It is possible to reduce it to just:
--   
--   <pre>
--   (f .) . (. g)
--   </pre>
--   
--   Which is one of the core pattern used by all related functions defined
--   in this module.
--   
--   Trying to generalize this pattern further ends as <tt>(f
--   <a>&lt;$&gt;</a>) <tt>.</tt> (<a>&lt;$&gt;</a> g)</tt>, where
--   <tt><a>&lt;$&gt;</a> = <a>fmap</a></tt>. Other combinations of
--   substituting <a>.</a> for <a>fmap</a> will end up less or equally
--   generic. Type of such expression is:
--   
--   <pre>
--   \f g -&gt; (f <a>&lt;$&gt;</a>) <a>.</a> (<a>&lt;$&gt;</a> g)
--       :: <a>Functor</a> f =&gt; (b -&gt; c) -&gt; f a -&gt; (a -&gt; b) -&gt; f c
--   </pre>
--   
--   Which doesn't give us much more power. Instead of going for such
--   generalization we kept the original <tt>((f .) . (. g))</tt> which we
--   named <a>between</a> or <a>~@~</a> in its infix form. There are other
--   possible generalizations possible, in example by using <a>.</a> from
--   <a>Control.Category</a> or by using composition from
--   <tt>Semigroupoid</tt> class, but that requires dependency on
--   <a>semigroupoids</a> package.
--   
--   Second concept/pattern exploited in this package is infix function
--   application with two arguments:
--   
--   <pre>
--   \(&lt;&gt;) -&gt; a &lt;&gt; b
--   </pre>
--   
--   Where <tt>a</tt> and <tt>b</tt> are fixed and <tt>&lt;&gt;</tt> is a
--   free variable. This library defines <a>inbetween</a> operator (also
--   called <a>~$~</a>, in its infix form) that embodies mentioned pattern:
--   
--   <pre>
--   <a>inbetween</a> :: a -&gt; b -&gt; (a -&gt; b -&gt; r) -&gt; r
--   <a>inbetween</a> a b f = a `<tt>f</tt>` b
--   </pre>
--   
--   <pre>
--   (<a>~$~</a>) :: a -&gt; b -&gt; (a -&gt; b -&gt; r) -&gt; r
--   (a <a>~$~</a> b) (&lt;&gt;) = a &lt;&gt; b
--   </pre>
module Data.Function.Between
