{- |
   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 = 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           = 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 forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& a b c2
c
                       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         = 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 forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& a b c3
d
                       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       = 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 forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& a b c4
e
                       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     = 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 forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& a b c5
f
                       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 forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& a b y
b forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> (c -> d) -> a b d
>>^ 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           = 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           forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> (c -> d) -> a b d
>>^ 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         = 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         forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> (c -> d) -> a b d
>>^ 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       = 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       forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> (c -> d) -> a b d
>>^ 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     = 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     forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> (c -> d) -> a b d
>>^ 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 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 = forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr forall a b. (a -> b) -> a -> 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 forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> (c -> d) -> a b 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 = forall (a :: * -> * -> *) b. Arrow a => a b b
returnA 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  = forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr b -> d
l 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 forall (a :: * -> * -> *) b d c.
ArrowChoice a =>
a b d -> a c d -> a (Either b c) d
||| 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  = forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr b -> d
l forall (a :: * -> * -> *) b d c.
ArrowChoice a =>
a b d -> a c d -> a (Either b 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 ^&&& :: forall (a :: * -> * -> *) b c c'.
Arrow a =>
(b -> c) -> a b c' -> a b (c, c')
^&&&  a b c'
r = forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr b -> c
l 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 forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, 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 = forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr 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 = forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr 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 = forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arrforall b c a. (b -> c) -> (a -> b) -> a -> 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 forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> (c -> d) -> a b d
>>^ 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 forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall a b. a -> Either a b
Left 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 forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> (c -> d) -> a b d
>>^ forall a b. a -> Either a b
Left forall (a :: * -> * -> *) b d c.
ArrowChoice a =>
(b -> d) -> (c -> d) -> a (Either b c) d
^|||^ forall a b. b -> Either a b
Right 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 forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall a b. a -> Either a b
Left 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 forall (a :: * -> * -> *) b c d.
Arrow a =>
(b -> c) -> a c d -> a b d
^>> forall a b. a -> Either a b
Left 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 forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a 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 forall (a :: * -> * -> *) x failure success success'.
ArrowChoice a =>
FallibleArrow a x failure success
-> (success -> success') -> FallibleArrow a x failure success'
>>?^ 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 forall (a :: * -> * -> *) x failure success success'.
ArrowChoice a =>
FallibleArrow a x failure success
-> (success -> Either failure success')
-> FallibleArrow a x failure success'
>>?^? 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 = forall (a :: * -> * -> *) b c. Arrow a => a b c -> a b (b, c)
keepingTheValue FallibleArrow a x f y
a forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall {a} {a} {b}. (a, Either a b) -> Either a b
repackage forall (a :: * -> * -> *) b c d.
Arrow a =>
(b -> c) -> a c d -> a b d
^>> (FallibleArrow a x f y
b forall (a :: * -> * -> *) b d c.
ArrowChoice a =>
a b d -> (c -> d) -> a (Either b c) d
|||^ forall a b. b -> Either a b
Right)
  where repackage :: (a, Either a b) -> Either a b
repackage (a
x , Left  a
_) = forall a b. a -> Either a b
Left  a
x
        repackage (a
_ , Right b
y) = forall a b. b -> Either a b
Right b
y

infixr 1 `ifFailedDo`