{- |
   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 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 :: a b c -> a b c' -> a b (c, c')
and2 = 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 :: 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 (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 :: 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 (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 :: 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 (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 :: 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 (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 :: (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 (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 :: (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 :: (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 :: (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 :: (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 :: (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 :: a b (b, b)
duplicate = (b -> (b, b)) -> a b (b, b)
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 >>% :: 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 :: 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 (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 ^||| :: (b -> d) -> a c d -> a (Either b c) d
^|||  a c d
r  = (b -> d) -> a b d
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 (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  |||^ :: 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 (a :: * -> * -> *) b d c.
ArrowChoice a =>
a b d -> a c d -> a (Either b c) d
||| (c -> d) -> a c d
forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr c -> d
r
b -> d
l ^|||^ :: (b -> d) -> (c -> d) -> a (Either b c) d
^|||^ c -> d
r  = (b -> d) -> a b d
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 (a :: * -> * -> *) b d c.
ArrowChoice a =>
a b d -> a c d -> a (Either b c) d
||| (c -> d) -> a c d
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 ^&&& :: (b -> c) -> a b c' -> a b (c, c')
^&&&  a b c'
r = (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 (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&&     a b c'
r
a b c
l  &&&^ :: 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 (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, 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 :: a (Either l r) (Maybe r)
choiceToMaybe = (Either l r -> Maybe r) -> a (Either l r) (Maybe r)
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 :: a (Maybe b) (Fallible b)
maybeToChoice = (Maybe b -> Fallible b) -> a (Maybe b) (Fallible b)
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 :: c -> a x c
returnV = (x -> c) -> a x 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 :: a x success -> FallibleArrow a x failure success
liftAsSuccess a x success
a   = a x success
a a x success
-> (success -> Either failure success)
-> FallibleArrow a x 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 >>? :: 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')
-> FallibleArrow a x 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 >>?^ :: 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')
-> FallibleArrow a x 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 >>?^? :: 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')
-> FallibleArrow a x 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 ^>>? :: (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')
-> FallibleArrow a x 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 >>?! :: 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')
-> FallibleArrow a x 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 (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 >>?% :: 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)
          => (x -> Either f (b,b'))
          -> (b -> b' -> c)
          -> FallibleArrow a x f c
x -> Either f (b, b')
a ^>>?% :: (x -> Either f (b, b')) -> (b -> b' -> c) -> FallibleArrow a x f c
^>>?% b -> b' -> c
f = (x -> Either f (b, b')) -> a x (Either f (b, b'))
forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr x -> Either f (b, b')
a a x (Either 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 >>?%? :: 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 :: 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`