    {- |
       Module      : Text.Pandoc.Readers.ODT.Arrows.Utils
       Copyright   : Copyright (C) 2015 Martin Linnemann
       License     : GNU GPL, version 2 or above

       Maintainer  : Martin Linnemann <theCodingMarlin@googlemail.com>
       Stability   : alpha
       Portability : portable

    Utility functions for Arrows (Kleisli monads).

    Some general notes on notation:

    * "^" is meant to stand for a pure function that is lifted into an arrow
    based on its usage for that purpose in "Control.Arrow".
    * "?" is meant to stand for the usage of a 'FallibleArrow' or a pure function
    with an equivalent return value.
    * "_" stands for the dropping of a value.
    -}

    -- We export everything
    module Text.Pandoc.Readers.ODT.Arrows.Utils where

    import Prelude hiding (Applicative(..))
    import Control.Arrow
    import Control.Monad (join)

    import Text.Pandoc.Readers.ODT.Generic.Fallible
    import Text.Pandoc.Readers.ODT.Generic.Utils

    and2 :: (Arrow a) => a b c -> a b c' -> a b (c,c')
    and2 :: forall (a :: * -> * -> *) b c c'.
    Arrow a =>
    a b c -> a b c' -> a b (c, c')
    and2 = a b c -> a b c' -> a b (c, c')
    forall b c c'. a b c -> a b c' -> a b (c, c')
    forall (a :: * -> * -> *) b c c'.
    Arrow a =>
    a b c -> a b c' -> a b (c, c')
    (&&&)

    and3 :: (Arrow a)
         => a b c0->a b c1->a b c2
         -> a b (c0,c1,c2               )
    and4 :: (Arrow a)
         => a b c0->a b c1->a b c2->a b c3
         -> a b (c0,c1,c2,c3            )
    and5 :: (Arrow a)
         => a b c0->a b c1->a b c2->a b c3->a b c4
         -> a b (c0,c1,c2,c3,c4         )
    and6 :: (Arrow a)
         => a b c0->a b c1->a b c2->a b c3->a b c4->a b c5
         -> a b (c0,c1,c2,c3,c4,c5      )

    and3 :: forall (a :: * -> * -> *) b c0 c1 c2.
    Arrow a =>
    a b c0 -> a b c1 -> a b c2 -> a b (c0, c1, c2)
    and3 a b c0
    a a b c1
    b a b c2
    c           = a b c0 -> a b c1 -> a b (c0, c1)
    forall (a :: * -> * -> *) b c c'.
    Arrow a =>
    a b c -> a b c' -> a b (c, c')
    and2 a b c0
    a a b c1
    b a b (c0, c1) -> a b c2 -> a b ((c0, c1), c2)
    forall b c c'. a b c -> a b c' -> a b (c, c')
    forall (a :: * -> * -> *) b c c'.
    Arrow a =>
    a b c -> a b c' -> a b (c, c')
    &&& a b c2
    c
                           a b ((c0, c1), c2)
    -> (((c0, c1), c2) -> (c0, c1, c2)) -> a b (c0, c1, c2)
    forall (a :: * -> * -> *) b c d.
    Arrow a =>
    a b c -> (c -> d) -> a b d
    >>^ \((c0
    z,c1
    y          ) , c2
    x) -> (c0
    z,c1
    y,c2
    x          )
    and4 :: forall (a :: * -> * -> *) b c0 c1 c2 c3.
    Arrow a =>
    a b c0 -> a b c1 -> a b c2 -> a b c3 -> a b (c0, c1, c2, c3)
    and4 a b c0
    a a b c1
    b a b c2
    c a b c3
    d         = a b c0 -> a b c1 -> a b c2 -> a b (c0, c1, c2)
    forall (a :: * -> * -> *) b c0 c1 c2.
    Arrow a =>
    a b c0 -> a b c1 -> a b c2 -> a b (c0, c1, c2)
    and3 a b c0
    a a b c1
    b a b c2
    c a b (c0, c1, c2) -> a b c3 -> a b ((c0, c1, c2), c3)
    forall b c c'. a b c -> a b c' -> a b (c, c')
    forall (a :: * -> * -> *) b c c'.
    Arrow a =>
    a b c -> a b c' -> a b (c, c')
    &&& a b c3
    d
                           a b ((c0, c1, c2), c3)
    -> (((c0, c1, c2), c3) -> (c0, c1, c2, c3)) -> a b (c0, c1, c2, c3)
    forall (a :: * -> * -> *) b c d.
    Arrow a =>
    a b c -> (c -> d) -> a b d
    >>^ \((c0
    z,c1
    y,c2
    x        ) , c3
    w) -> (c0
    z,c1
    y,c2
    x,c3
    w        )
    and5 :: forall (a :: * -> * -> *) b c0 c1 c2 c3 c4.
    Arrow a =>
    a b c0
    -> a b c1 -> a b c2 -> a b c3 -> a b c4 -> a b (c0, c1, c2, c3, c4)
    and5 a b c0
    a a b c1
    b a b c2
    c a b c3
    d a b c4
    e       = a b c0 -> a b c1 -> a b c2 -> a b c3 -> a b (c0, c1, c2, c3)
    forall (a :: * -> * -> *) b c0 c1 c2 c3.
    Arrow a =>
    a b c0 -> a b c1 -> a b c2 -> a b c3 -> a b (c0, c1, c2, c3)
    and4 a b c0
    a a b c1
    b a b c2
    c a b c3
    d a b (c0, c1, c2, c3) -> a b c4 -> a b ((c0, c1, c2, c3), c4)
    forall b c c'. a b c -> a b c' -> a b (c, c')
    forall (a :: * -> * -> *) b c c'.
    Arrow a =>
    a b c -> a b c' -> a b (c, c')
    &&& a b c4
    e
                           a b ((c0, c1, c2, c3), c4)
    -> (((c0, c1, c2, c3), c4) -> (c0, c1, c2, c3, c4))
    -> a b (c0, c1, c2, c3, c4)
    forall (a :: * -> * -> *) b c d.
    Arrow a =>
    a b c -> (c -> d) -> a b d
    >>^ \((c0
    z,c1
    y,c2
    x,c3
    w      ) , c4
    v) -> (c0
    z,c1
    y,c2
    x,c3
    w,c4
    v      )
    and6 :: forall (a :: * -> * -> *) b c0 c1 c2 c3 c4 c5.
    Arrow a =>
    a b c0
    -> a b c1
    -> a b c2
    -> a b c3
    -> a b c4
    -> a b c5
    -> a b (c0, c1, c2, c3, c4, c5)
    and6 a b c0
    a a b c1
    b a b c2
    c a b c3
    d a b c4
    e a b c5
    f     = a b c0
    -> a b c1 -> a b c2 -> a b c3 -> a b c4 -> a b (c0, c1, c2, c3, c4)
    forall (a :: * -> * -> *) b c0 c1 c2 c3 c4.
    Arrow a =>
    a b c0
    -> a b c1 -> a b c2 -> a b c3 -> a b c4 -> a b (c0, c1, c2, c3, c4)
    and5 a b c0
    a a b c1
    b a b c2
    c a b c3
    d a b c4
    e a b (c0, c1, c2, c3, c4)
    -> a b c5 -> a b ((c0, c1, c2, c3, c4), c5)
    forall b c c'. a b c -> a b c' -> a b (c, c')
    forall (a :: * -> * -> *) b c c'.
    Arrow a =>
    a b c -> a b c' -> a b (c, c')
    &&& a b c5
    f
                           a b ((c0, c1, c2, c3, c4), c5)
    -> (((c0, c1, c2, c3, c4), c5) -> (c0, c1, c2, c3, c4, c5))
    -> a b (c0, c1, c2, c3, c4, c5)
    forall (a :: * -> * -> *) b c d.
    Arrow a =>
    a b c -> (c -> d) -> a b d
    >>^ \((c0
    z,c1
    y,c2
    x,c3
    w,c4
    v    ) , c5
    u) -> (c0
    z,c1
    y,c2
    x,c3
    w,c4
    v,c5
    u    )

    liftA2 :: (Arrow a) => (x -> y -> z) -> a b x -> a b y -> a b z
    liftA2 :: forall (a :: * -> * -> *) x y z b.
    Arrow a =>
    (x -> y -> z) -> a b x -> a b y -> a b z
    liftA2 x -> y -> z
    f a b x
    a a b y
    b = a b x
    a a b x -> a b y -> a b (x, y)
    forall b c c'. a b c -> a b c' -> a b (c, c')
    forall (a :: * -> * -> *) b c c'.
    Arrow a =>
    a b c -> a b c' -> a b (c, c')
    &&& a b y
    b a b (x, y) -> ((x, y) -> z) -> a b z
    forall (a :: * -> * -> *) b c d.
    Arrow a =>
    a b c -> (c -> d) -> a b d
    >>^ (x -> y -> z) -> (x, y) -> z
    forall a b c. (a -> b -> c) -> (a, b) -> c
    uncurry x -> y -> z
    f

    liftA3 :: (Arrow a) => (z->y->x                -> r)
                        -> a b z->a b y->a b x
                        -> a b r
    liftA4 :: (Arrow a) => (z->y->x->w             -> r)
                        -> a b z->a b y->a b x->a b w
                        -> a b r
    liftA5 :: (Arrow a) => (z->y->x->w->v          -> r)
                        -> a b z->a b y->a b x->a b w->a b v
                        -> a b r
    liftA6 :: (Arrow a) => (z->y->x->w->v->u       -> r)
                        -> a b z->a b y->a b x->a b w->a b v->a b u
                        -> a b r

    liftA3 :: forall (a :: * -> * -> *) z y x r b.
    Arrow a =>
    (z -> y -> x -> r) -> a b z -> a b y -> a b x -> a b r
    liftA3 z -> y -> x -> r
    fun a b z
    a a b y
    b a b x
    c           = a b z -> a b y -> a b x -> a b (z, y, x)
    forall (a :: * -> * -> *) b c0 c1 c2.
    Arrow a =>
    a b c0 -> a b c1 -> a b c2 -> a b (c0, c1, c2)
    and3 a b z
    a a b y
    b a b x
    c           a b (z, y, x) -> ((z, y, x) -> r) -> a b r
    forall (a :: * -> * -> *) b c d.
    Arrow a =>
    a b c -> (c -> d) -> a b d
    >>^ (z -> y -> x -> r) -> (z, y, x) -> r
    forall a b c z. (a -> b -> c -> z) -> (a, b, c) -> z
    uncurry3 z -> y -> x -> r
    fun
    liftA4 :: forall (a :: * -> * -> *) z y x w r b.
    Arrow a =>
    (z -> y -> x -> w -> r)
    -> a b z -> a b y -> a b x -> a b w -> a b r
    liftA4 z -> y -> x -> w -> r
    fun a b z
    a a b y
    b a b x
    c a b w
    d         = a b z -> a b y -> a b x -> a b w -> a b (z, y, x, w)
    forall (a :: * -> * -> *) b c0 c1 c2 c3.
    Arrow a =>
    a b c0 -> a b c1 -> a b c2 -> a b c3 -> a b (c0, c1, c2, c3)
    and4 a b z
    a a b y
    b a b x
    c a b w
    d         a b (z, y, x, w) -> ((z, y, x, w) -> r) -> a b r
    forall (a :: * -> * -> *) b c d.
    Arrow a =>
    a b c -> (c -> d) -> a b d
    >>^ (z -> y -> x -> w -> r) -> (z, y, x, w) -> r
    forall a b c d z. (a -> b -> c -> d -> z) -> (a, b, c, d) -> z
    uncurry4 z -> y -> x -> w -> r
    fun
    liftA5 :: forall (a :: * -> * -> *) z y x w v r b.
    Arrow a =>
    (z -> y -> x -> w -> v -> r)
    -> a b z -> a b y -> a b x -> a b w -> a b v -> a b r
    liftA5 z -> y -> x -> w -> v -> r
    fun a b z
    a a b y
    b a b x
    c a b w
    d a b v
    e       = a b z -> a b y -> a b x -> a b w -> a b v -> a b (z, y, x, w, v)
    forall (a :: * -> * -> *) b c0 c1 c2 c3 c4.
    Arrow a =>
    a b c0
    -> a b c1 -> a b c2 -> a b c3 -> a b c4 -> a b (c0, c1, c2, c3, c4)
    and5 a b z
    a a b y
    b a b x
    c a b w
    d a b v
    e       a b (z, y, x, w, v) -> ((z, y, x, w, v) -> r) -> a b r
    forall (a :: * -> * -> *) b c d.
    Arrow a =>
    a b c -> (c -> d) -> a b d
    >>^ (z -> y -> x -> w -> v -> r) -> (z, y, x, w, v) -> r
    forall a b c d e z.
    (a -> b -> c -> d -> e -> z) -> (a, b, c, d, e) -> z
    uncurry5 z -> y -> x -> w -> v -> r
    fun
    liftA6 :: forall (a :: * -> * -> *) z y x w v u r b.
    Arrow a =>
    (z -> y -> x -> w -> v -> u -> r)
    -> a b z -> a b y -> a b x -> a b w -> a b v -> a b u -> a b r
    liftA6 z -> y -> x -> w -> v -> u -> r
    fun a b z
    a a b y
    b a b x
    c a b w
    d a b v
    e a b u
    f     = a b z
    -> a b y
    -> a b x
    -> a b w
    -> a b v
    -> a b u
    -> a b (z, y, x, w, v, u)
    forall (a :: * -> * -> *) b c0 c1 c2 c3 c4 c5.
    Arrow a =>
    a b c0
    -> a b c1
    -> a b c2
    -> a b c3
    -> a b c4
    -> a b c5
    -> a b (c0, c1, c2, c3, c4, c5)
    and6 a b z
    a a b y
    b a b x
    c a b w
    d a b v
    e a b u
    f     a b (z, y, x, w, v, u) -> ((z, y, x, w, v, u) -> r) -> a b r
    forall (a :: * -> * -> *) b c d.
    Arrow a =>
    a b c -> (c -> d) -> a b d
    >>^ (z -> y -> x -> w -> v -> u -> r) -> (z, y, x, w, v, u) -> r
    forall a b c d e f z.
    (a -> b -> c -> d -> e -> f -> z) -> (a, b, c, d, e, f) -> z
    uncurry6 z -> y -> x -> w -> v -> u -> r
    fun

    liftA :: (Arrow a) => (y -> z) -> a b y -> a b z
    liftA :: forall (a :: * -> * -> *) y z b.
    Arrow a =>
    (y -> z) -> a b y -> a b z
    liftA  y -> z
    fun a b y
    a = a b y
    a a b y -> (y -> z) -> a b z
    forall (a :: * -> * -> *) b c d.
    Arrow a =>
    a b c -> (c -> d) -> a b d
    >>^ y -> z
    fun

    -- | Duplicate a value to subsequently feed it into different arrows.
    -- Can almost always be replaced with '(&&&)', 'keepingTheValue',
    -- or even '(|||)'.
    -- Equivalent to
    -- > returnA &&& returnA
    duplicate :: (Arrow a) => a b (b,b)
    duplicate :: forall (a :: * -> * -> *) b. Arrow a => a b (b, b)
    duplicate = (b -> (b, b)) -> a b (b, b)
    forall b c. (b -> c) -> a b c
    forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
    arr ((b -> (b, b)) -> a b (b, b)) -> (b -> (b, b)) -> a b (b, b)
    forall a b. (a -> b) -> a -> b
    $ (b -> b -> (b, b)) -> b -> (b, b)
    forall (m :: * -> *) a. Monad m => m (m a) -> m a
    join (,)

    -- | Applies a function to the uncurried result-pair of an arrow-application.
    -- (The %-symbol was chosen to evoke an association with pairs.)
    (>>%) :: (Arrow a) => a x (b,c) -> (b -> c -> d) -> a x d
    a x (b, c)
    a >>% :: forall (a :: * -> * -> *) x b c d.
    Arrow a =>
    a x (b, c) -> (b -> c -> d) -> a x d
    >>% b -> c -> d
    f = a x (b, c)
    a a x (b, c) -> ((b, c) -> d) -> a x d
    forall (a :: * -> * -> *) b c d.
    Arrow a =>
    a b c -> (c -> d) -> a b d
    >>^ (b -> c -> d) -> (b, c) -> d
    forall a b c. (a -> b -> c) -> (a, b) -> c
    uncurry b -> c -> d
    f

    infixr 2 >>%

    -- | Duplicate a value and apply an arrow to the second instance.
    -- Equivalent to
    -- > \a -> duplicate >>> second a
    -- or
    -- > \a -> returnA &&& a
    keepingTheValue :: (Arrow a) => a b c -> a b (b,c)
    keepingTheValue :: forall (a :: * -> * -> *) b c. Arrow a => a b c -> a b (b, c)
    keepingTheValue a b c
    a = a b b
    forall (a :: * -> * -> *) b. Arrow a => a b b
    returnA a b b -> a b c -> a b (b, c)
    forall b c c'. a b c -> a b c' -> a b (c, c')
    forall (a :: * -> * -> *) b c c'.
    Arrow a =>
    a b c -> a b c' -> a b (c, c')
    &&& a b c
    a

    ( ^|||  ) :: (ArrowChoice a) => (b -> d) ->  a c d   -> a (Either b c) d
    (  |||^ ) :: (ArrowChoice a) =>  a b d   -> (c -> d) -> a (Either b c) d
    ( ^|||^ ) :: (ArrowChoice a) => (b -> d) -> (c -> d) -> a (Either b c) d

    b -> d
    l ^||| :: forall (a :: * -> * -> *) b d c.
    ArrowChoice a =>
    (b -> d) -> a c d -> a (Either b c) d
    ^|||  a c d
    r  = (b -> d) -> a b d
    forall b c. (b -> c) -> a b c
    forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
    arr b -> d
    l a b d -> a c d -> a (Either b c) d
    forall b d c. a b d -> a c d -> a (Either b c) d
    forall (a :: * -> * -> *) b d c.
    ArrowChoice a =>
    a b d -> a c d -> a (Either b c) d
    |||     a c d
    r
    a b d
    l  |||^ :: forall (a :: * -> * -> *) b d c.
    ArrowChoice a =>
    a b d -> (c -> d) -> a (Either b c) d
    |||^ c -> d
    r  =     a b d
    l a b d -> a c d -> a (Either b c) d
    forall b d c. a b d -> a c d -> a (Either b c) d
    forall (a :: * -> * -> *) b d c.
    ArrowChoice a =>
    a b d -> a c d -> a (Either b c) d
    ||| (c -> d) -> a c d
    forall b c. (b -> c) -> a b c
    forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
    arr c -> d
    r
    b -> d
    l ^|||^ :: forall (a :: * -> * -> *) b d c.
    ArrowChoice a =>
    (b -> d) -> (c -> d) -> a (Either b c) d
    ^|||^ c -> d
    r  = (b -> d) -> a b d
    forall b c. (b -> c) -> a b c
    forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
    arr b -> d
    l a b d -> a c d -> a (Either b c) d
    forall b d c. a b d -> a c d -> a (Either b c) d
    forall (a :: * -> * -> *) b d c.
    ArrowChoice a =>
    a b d -> a c d -> a (Either b c) d
    ||| (c -> d) -> a c d
    forall b c. (b -> c) -> a b c
    forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
    arr c -> d
    r

    infixr 2 ^||| ,  |||^, ^|||^

    ( ^&&&  ) :: (Arrow a) => (b -> c) ->  a b c'   -> a b (c,c')
    (  &&&^ ) :: (Arrow a) =>  a b c   -> (b -> c') -> a b (c,c')

    b -> c
    l ^&&& :: forall (a :: * -> * -> *) b c c'.
    Arrow a =>
    (b -> c) -> a b c' -> a b (c, c')
    ^&&&  a b c'
    r = (b -> c) -> a b c
    forall b c. (b -> c) -> a b c
    forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
    arr b -> c
    l a b c -> a b c' -> a b (c, c')
    forall b c c'. a b c -> a b c' -> a b (c, c')
    forall (a :: * -> * -> *) b c c'.
    Arrow a =>
    a b c -> a b c' -> a b (c, c')
    &&&     a b c'
    r
    a b c
    l  &&&^ :: forall (a :: * -> * -> *) b c c'.
    Arrow a =>
    a b c -> (b -> c') -> a b (c, c')
    &&&^ b -> c'
    r =     a b c
    l a b c -> a b c' -> a b (c, c')
    forall b c c'. a b c -> a b c' -> a b (c, c')
    forall (a :: * -> * -> *) b c c'.
    Arrow a =>
    a b c -> a b c' -> a b (c, c')
    &&& (b -> c') -> a b c'
    forall b c. (b -> c) -> a b c
    forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
    arr b -> c'
    r

    infixr 3 ^&&&, &&&^

    -- | Converts @Right a@ into @Just a@ and @Left _@ into @Nothing@.
    choiceToMaybe :: (ArrowChoice a) => a (Either l r) (Maybe r)
    choiceToMaybe :: forall (a :: * -> * -> *) l r.
    ArrowChoice a =>
    a (Either l r) (Maybe r)
    choiceToMaybe = (Either l r -> Maybe r) -> a (Either l r) (Maybe r)
    forall b c. (b -> c) -> a b c
    forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
    arr Either l r -> Maybe r
    forall _l a. Either _l a -> Maybe a
    eitherToMaybe

    -- | Converts @Nothing@ into @Left ()@ and @Just a@ into @Right a@.
    maybeToChoice :: (ArrowChoice a) => a (Maybe b) (Fallible b)
    maybeToChoice :: forall (a :: * -> * -> *) b.
    ArrowChoice a =>
    a (Maybe b) (Fallible b)
    maybeToChoice = (Maybe b -> Fallible b) -> a (Maybe b) (Fallible b)
    forall b c. (b -> c) -> a b c
    forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
    arr Maybe b -> Fallible b
    forall a. Maybe a -> Fallible a
    maybeToEither

    -- | Lifts a constant value into an arrow
    returnV :: (Arrow a) => c -> a x c
    returnV :: forall (a :: * -> * -> *) c x. Arrow a => c -> a x c
    returnV = (x -> c) -> a x c
    forall b c. (b -> c) -> a b c
    forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
    arr((x -> c) -> a x c) -> (c -> x -> c) -> c -> a x c
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .c -> x -> c
    forall a b. a -> b -> a
    const

    -- | Defines Left as failure, Right as success
    type FallibleArrow a input failure success = a input (Either failure success)

    --
    liftAsSuccess     :: (ArrowChoice a)
                      => a x success
                      -> FallibleArrow a x failure success
    liftAsSuccess :: forall (a :: * -> * -> *) x success failure.
    ArrowChoice a =>
    a x success -> FallibleArrow a x failure success
    liftAsSuccess a x success
    a   = a x success
    a a x success
    -> (success -> Either failure success)
    -> a x (Either failure success)
    forall (a :: * -> * -> *) b c d.
    Arrow a =>
    a b c -> (c -> d) -> a b d
    >>^ success -> Either failure success
    forall a b. b -> Either a b
    Right

    -- | Execute the second arrow if the first succeeds
    (>>?) :: (ArrowChoice a)
                => FallibleArrow a x       failure success
                -> FallibleArrow a success failure success'
                -> FallibleArrow a x       failure success'
    FallibleArrow a x failure success
    a >>? :: forall (a :: * -> * -> *) x failure success success'.
    ArrowChoice a =>
    FallibleArrow a x failure success
    -> FallibleArrow a success failure success'
    -> FallibleArrow a x failure success'
    >>? FallibleArrow a success failure success'
    b = FallibleArrow a x failure success
    a FallibleArrow a x failure success
    -> a (Either failure success) (Either failure success')
    -> a x (Either failure success')
    forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
    Category cat =>
    cat a b -> cat b c -> cat a c
    >>> failure -> Either failure success'
    forall a b. a -> Either a b
    Left (failure -> Either failure success')
    -> FallibleArrow a success failure success'
    -> a (Either failure success) (Either failure success')
    forall (a :: * -> * -> *) b d c.
    ArrowChoice a =>
    (b -> d) -> a c d -> a (Either b c) d
    ^||| FallibleArrow a success failure success'
    b

    -- | Execute the lifted second arrow if the first succeeds
    (>>?^) :: (ArrowChoice a)
                => FallibleArrow a x       failure success
                -> (success                     -> success')
                -> FallibleArrow a x       failure success'
    FallibleArrow a x failure success
    a >>?^ :: forall (a :: * -> * -> *) x failure success success'.
    ArrowChoice a =>
    FallibleArrow a x failure success
    -> (success -> success') -> FallibleArrow a x failure success'
    >>?^ success -> success'
    f = FallibleArrow a x failure success
    a FallibleArrow a x failure success
    -> (Either failure success -> Either failure success')
    -> a x (Either failure success')
    forall (a :: * -> * -> *) b c d.
    Arrow a =>
    a b c -> (c -> d) -> a b d
    >>^ failure -> Either failure success'
    forall a b. a -> Either a b
    Left (failure -> Either failure success')
    -> (success -> Either failure success')
    -> Either failure success
    -> Either failure success'
    forall (a :: * -> * -> *) b d c.
    ArrowChoice a =>
    (b -> d) -> (c -> d) -> a (Either b c) d
    ^|||^ success' -> Either failure success'
    forall a b. b -> Either a b
    Right (success' -> Either failure success')
    -> (success -> success') -> success -> Either failure success'
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . success -> success'
    f

    -- | Execute the lifted second arrow if the first succeeds
    (>>?^?) :: (ArrowChoice a)
                => FallibleArrow a x       failure success
                -> (success      -> Either failure success')
                -> FallibleArrow a x       failure success'
    FallibleArrow a x failure success
    a >>?^? :: forall (a :: * -> * -> *) x failure success success'.
    ArrowChoice a =>
    FallibleArrow a x failure success
    -> (success -> Either failure success')
    -> FallibleArrow a x failure success'
    >>?^? success -> Either failure success'
    b = FallibleArrow a x failure success
    a FallibleArrow a x failure success
    -> a (Either failure success) (Either failure success')
    -> a x (Either failure success')
    forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
    Category cat =>
    cat a b -> cat b c -> cat a c
    >>> failure -> Either failure success'
    forall a b. a -> Either a b
    Left (failure -> Either failure success')
    -> (success -> Either failure success')
    -> a (Either failure success) (Either failure success')
    forall (a :: * -> * -> *) b d c.
    ArrowChoice a =>
    (b -> d) -> (c -> d) -> a (Either b c) d
    ^|||^ success -> Either failure success'
    b

    -- | Execute the second arrow if the lifted first arrow succeeds
    (^>>?) :: (ArrowChoice a)
                => (x            -> Either failure success)
                -> FallibleArrow a success failure success'
                -> FallibleArrow a x       failure success'
    x -> Either failure success
    a ^>>? :: forall (a :: * -> * -> *) x failure success success'.
    ArrowChoice a =>
    (x -> Either failure success)
    -> FallibleArrow a success failure success'
    -> FallibleArrow a x failure success'
    ^>>? FallibleArrow a success failure success'
    b = x -> Either failure success
    a (x -> Either failure success)
    -> a (Either failure success) (Either failure success')
    -> a x (Either failure success')
    forall (a :: * -> * -> *) b c d.
    Arrow a =>
    (b -> c) -> a c d -> a b d
    ^>> failure -> Either failure success'
    forall a b. a -> Either a b
    Left (failure -> Either failure success')
    -> FallibleArrow a success failure success'
    -> a (Either failure success) (Either failure success')
    forall (a :: * -> * -> *) b d c.
    ArrowChoice a =>
    (b -> d) -> a c d -> a (Either b c) d
    ^||| FallibleArrow a success failure success'
    b

    -- | Execute the second, non-fallible arrow if the first arrow succeeds
    (>>?!) :: (ArrowChoice a)
                => FallibleArrow a x       failure success
                ->               a success         success'
                -> FallibleArrow a x       failure success'
    FallibleArrow a x failure success
    a >>?! :: forall (a :: * -> * -> *) x failure success success'.
    ArrowChoice a =>
    FallibleArrow a x failure success
    -> a success success' -> FallibleArrow a x failure success'
    >>?! a success success'
    f = FallibleArrow a x failure success
    a FallibleArrow a x failure success
    -> a (Either failure success) (Either failure success')
    -> a x (Either failure success')
    forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
    Category cat =>
    cat a b -> cat b c -> cat a c
    >>> a success success'
    -> a (Either failure success) (Either failure success')
    forall b c d. a b c -> a (Either d b) (Either d c)
    forall (a :: * -> * -> *) b c d.
    ArrowChoice a =>
    a b c -> a (Either d b) (Either d c)
    right a success success'
    f

    ---
    (>>?%) :: (ArrowChoice a)
              => FallibleArrow a x f (b,b')
              -> (b -> b' -> c)
              -> FallibleArrow a x f c
    FallibleArrow a x f (b, b')
    a >>?% :: forall (a :: * -> * -> *) x f b b' c.
    ArrowChoice a =>
    FallibleArrow a x f (b, b')
    -> (b -> b' -> c) -> FallibleArrow a x f c
    >>?% b -> b' -> c
    f = FallibleArrow a x f (b, b')
    a FallibleArrow a x f (b, b')
    -> ((b, b') -> c) -> FallibleArrow a x f c
    forall (a :: * -> * -> *) x failure success success'.
    ArrowChoice a =>
    FallibleArrow a x failure success
    -> (success -> success') -> FallibleArrow a x failure success'
    >>?^ (b -> b' -> c) -> (b, b') -> c
    forall a b c. (a -> b -> c) -> (a, b) -> c
    uncurry b -> b' -> c
    f

    ---
    (>>?%?) :: (ArrowChoice a)
               => FallibleArrow a x f (b,b')
               -> (b -> b' -> Either f c)
               -> FallibleArrow a x f c
    FallibleArrow a x f (b, b')
    a >>?%? :: forall (a :: * -> * -> *) x f b b' c.
    ArrowChoice a =>
    FallibleArrow a x f (b, b')
    -> (b -> b' -> Either f c) -> FallibleArrow a x f c
    >>?%? b -> b' -> Either f c
    f = FallibleArrow a x f (b, b')
    a FallibleArrow a x f (b, b')
    -> ((b, b') -> Either f c) -> FallibleArrow a x f c
    forall (a :: * -> * -> *) x failure success success'.
    ArrowChoice a =>
    FallibleArrow a x failure success
    -> (success -> Either failure success')
    -> FallibleArrow a x failure success'
    >>?^? (b -> b' -> Either f c) -> (b, b') -> Either f c
    forall a b c. (a -> b -> c) -> (a, b) -> c
    uncurry b -> b' -> Either f c
    f

    infixr 1  >>?,  >>?^,  >>?^?
    infixr 1 ^>>?, >>?!
    infixr 1 >>?%, >>?%?

    -- | An arrow version of a short-circuit (<|>)
    ifFailedDo :: (ArrowChoice a)
               => FallibleArrow a x f y
               -> FallibleArrow a x f y
               -> FallibleArrow a x f y
    ifFailedDo :: forall (a :: * -> * -> *) x f y.
    ArrowChoice a =>
    FallibleArrow a x f y
    -> FallibleArrow a x f y -> FallibleArrow a x f y
    ifFailedDo FallibleArrow a x f y
    a FallibleArrow a x f y
    b = FallibleArrow a x f y -> a x (x, Either f y)
    forall (a :: * -> * -> *) b c. Arrow a => a b c -> a b (b, c)
    keepingTheValue FallibleArrow a x f y
    a a x (x, Either f y)
    -> a (x, Either f y) (Either f y) -> FallibleArrow a x f y
    forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
    Category cat =>
    cat a b -> cat b c -> cat a c
    >>> (x, Either f y) -> Either x y
    forall {a} {a} {b}. (a, Either a b) -> Either a b
    repackage ((x, Either f y) -> Either x y)
    -> a (Either x y) (Either f y) -> a (x, Either f y) (Either f y)
    forall (a :: * -> * -> *) b c d.
    Arrow a =>
    (b -> c) -> a c d -> a b d
    ^>> (FallibleArrow a x f y
    b FallibleArrow a x f y
    -> (y -> Either f y) -> a (Either x y) (Either f y)
    forall (a :: * -> * -> *) b d c.
    ArrowChoice a =>
    a b d -> (c -> d) -> a (Either b c) d
    |||^ y -> Either f y
    forall a b. b -> Either a b
    Right)
      where repackage :: (a, Either a b) -> Either a b
    repackage (a
    x , Left  a
    _) = a -> Either a b
    forall a b. a -> Either a b
    Left  a
    x
            repackage (a
    _ , Right b
    y) = b -> Either a b
    forall a b. b -> Either a b
    Right b
    y

    infixr 1 `ifFailedDo`