@@ -40,10 +40,7 @@ with an equivalent return value.
40module Text.Pandoc.Readers.Odt.Arrows.Utils where
40module Text.Pandoc.Readers.Odt.Arrows.Utils where
42import Control.Arrow
42import Control.Arrow
43−import Control.Monad ( join, MonadPlus(..) )
43+import Control.Monad ( join )
45−import qualified Data.Foldable as F
48import Text.Pandoc.Readers.Odt.Generic.Fallible
45import Text.Pandoc.Readers.Odt.Generic.Fallible
49import Text.Pandoc.Readers.Odt.Generic.Utils
46import Text.Pandoc.Readers.Odt.Generic.Utils
@@ -63,12 +60,6 @@ and5 :: (Arrow a)
63and6 :: (Arrow a)
60and6 :: (Arrow a)
64 => a b c0->a b c1->a b c2->a b c3->a b c4->a b c5
61 => a b c0->a b c1->a b c2->a b c3->a b c4->a b c5
65 -> a b (c0,c1,c2,c3,c4,c5 )
62 -> a b (c0,c1,c2,c3,c4,c5 )
67− => a b c0->a b c1->a b c2->a b c3->a b c4->a b c5->a b c6
68− -> a b (c0,c1,c2,c3,c4,c5,c6 )
70− => a b c0->a b c1->a b c2->a b c3->a b c4->a b c5->a b c6->a b c7
71− -> a b (c0,c1,c2,c3,c4,c5,c6,c7)
73and3 a b c = (and2 a b ) &&& c
64and3 a b c = (and2 a b ) &&& c
74 >>^ \((z,y ) , x) -> (z,y,x )
65 >>^ \((z,y ) , x) -> (z,y,x )
@@ -78,10 +69,6 @@ and5 a b c d e = (and4 a b c d ) &&& e
78 >>^ \((z,y,x,w ) , v) -> (z,y,x,w,v )
69 >>^ \((z,y,x,w ) , v) -> (z,y,x,w,v )
79and6 a b c d e f = (and5 a b c d e ) &&& f
70and6 a b c d e f = (and5 a b c d e ) &&& f
80 >>^ \((z,y,x,w,v ) , u) -> (z,y,x,w,v,u )
71 >>^ \((z,y,x,w,v ) , u) -> (z,y,x,w,v,u )
81−and7 a b c d e f g = (and6 a b c d e f ) &&& g
82− >>^ \((z,y,x,w,v,u ) , t) -> (z,y,x,w,v,u,t )
83−and8 a b c d e f g h = (and7 a b c d e f g) &&& h
84− >>^ \((z,y,x,w,v,u,t) , s) -> (z,y,x,w,v,u,t,s)
86liftA2 :: (Arrow a) => (x -> y -> z) -> a b x -> a b y -> a b z
73liftA2 :: (Arrow a) => (x -> y -> z) -> a b x -> a b y -> a b z
87liftA2 f a b = a &&& b >>^ uncurry f
74liftA2 f a b = a &&& b >>^ uncurry f
@@ -98,19 +85,11 @@ liftA5 :: (Arrow a) => (z->y->x->w->v -> r)
98liftA6 :: (Arrow a) => (z->y->x->w->v->u -> r)
85liftA6 :: (Arrow a) => (z->y->x->w->v->u -> r)
99 -> a b z->a b y->a b x->a b w->a b v->a b u
86 -> a b z->a b y->a b x->a b w->a b v->a b u
101−liftA7 :: (Arrow a) => (z->y->x->w->v->u->t -> r)
102− -> a b z->a b y->a b x->a b w->a b v->a b u->a b t
104−liftA8 :: (Arrow a) => (z->y->x->w->v->u->t->s -> r)
105− -> a b z->a b y->a b x->a b w->a b v->a b u->a b t->a b s
108liftA3 fun a b c = and3 a b c >>^ uncurry3 fun
89liftA3 fun a b c = and3 a b c >>^ uncurry3 fun
109liftA4 fun a b c d = and4 a b c d >>^ uncurry4 fun
90liftA4 fun a b c d = and4 a b c d >>^ uncurry4 fun
110liftA5 fun a b c d e = and5 a b c d e >>^ uncurry5 fun
91liftA5 fun a b c d e = and5 a b c d e >>^ uncurry5 fun
111liftA6 fun a b c d e f = and6 a b c d e f >>^ uncurry6 fun
92liftA6 fun a b c d e f = and6 a b c d e f >>^ uncurry6 fun
112−liftA7 fun a b c d e f g = and7 a b c d e f g >>^ uncurry7 fun
113−liftA8 fun a b c d e f g h = and8 a b c d e f g h >>^ uncurry8 fun
115liftA :: (Arrow a) => (y -> z) -> a b y -> a b z
94liftA :: (Arrow a) => (y -> z) -> a b y -> a b z
116liftA fun a = a >>^ fun
95liftA fun a = a >>^ fun
@@ -124,28 +103,12 @@ liftA fun a = a >>^ fun
124duplicate :: (Arrow a) => a b (b,b)
103duplicate :: (Arrow a) => a b (b,b)
125duplicate = arr $ join (,)
104duplicate = arr $ join (,)
127−-- | Lifts the combination of two values into an arrow.
128−joinOn :: (Arrow a) => (x -> y -> z) -> a (x,y) z
131-- | Applies a function to the uncurried result-pair of an arrow-application.
106-- | Applies a function to the uncurried result-pair of an arrow-application.
132-- (The %-symbol was chosen to evoke an association with pairs.)
107-- (The %-symbol was chosen to evoke an association with pairs.)
133(>>%) :: (Arrow a) => a x (b,c) -> (b -> c -> d) -> a x d
108(>>%) :: (Arrow a) => a x (b,c) -> (b -> c -> d) -> a x d
134a >>% f = a >>^ uncurry f
109a >>% f = a >>^ uncurry f
136−-- | '(>>%)' with its arguments flipped
137−(%<<) :: (Arrow a) => (b -> c -> d) -> a x (b,c) -> a x d
140−-- | Precomposition with an uncurried function
141−(%>>) :: (Arrow a) => (b -> c -> d) -> a d r -> a (b,c) r
142−f %>> a = uncurry f ^>> a
144−-- | Precomposition with an uncurried function (right to left variant)
145−(<<%) :: (Arrow a) => a d r -> (b -> c -> d) -> a (b,c) r
148−infixr 2 >>%, %<<, %>>, <<%
111+infixr 2 >>%
151-- | Duplicate a value and apply an arrow to the second instance.
114-- | Duplicate a value and apply an arrow to the second instance.
@@ -156,56 +119,6 @@ infixr 2 >>%, %<<, %>>, <<%
156keepingTheValue :: (Arrow a) => a b c -> a b (b,c)
119keepingTheValue :: (Arrow a) => a b c -> a b (b,c)
157keepingTheValue a = returnA &&& a
120keepingTheValue a = returnA &&& a
159−-- | Duplicate a value and apply an arrow to the first instance.
161−-- > \a -> duplicate >>> first a
163−-- > \a -> a &&& returnA
164−keepingTheValue' :: (Arrow a) => a b c -> a b (c,b)
165−keepingTheValue' a = a &&& returnA
167−-- | 'bind' from the "Maybe"-Monad lifted into an 'ArrowChoice'.
168−-- Actually, it's the more complex '(>=>)', because 'bind' alone does not
169−-- combine as nicely in arrow form.
170−-- The current implementation is not the most efficient one, because it can
171−-- not return directly if a 'Nothing' is encountered. That in turn follows
172−-- from the type system, as 'Nothing' has an "invisible" type parameter that
173−-- can not be dropped early.
175−-- Also, there probably is a way to generalize this to other monads
176−-- or applicatives, but I'm leaving that as an exercise to the reader.
177−-- I have a feeling there is a new Arrow-typeclass to be found that is less
178−-- restrictive than 'ArrowApply'. If it is already out there,
179−-- I have not seen it yet. ('ArrowPlus' for example is not general enough.)
180−(>>>=) :: (ArrowChoice a) => a x (Maybe b) -> a b (Maybe c) -> a x (Maybe c)
181−a1 >>>= a2 = a1 >>> maybeToChoice >>> right a2 >>> choiceToMaybe >>^ join
185−-- | 'mplus' Lifted into an arrow. No 'ArrowPlus' required.
186−-- (But still different from a true bind)
187−(>++<) :: (Arrow a, MonadPlus m) => a x (m b) -> a x (m b) -> a x (m b)
188−(>++<) = liftA2 mplus
190−-- | Left-compose with a pure function
191−leftLift :: (ArrowChoice a) => (l -> l') -> a (Either l r) (Either l' r)
194−-- | Right-compose with a pure function
195−rightLift :: (ArrowChoice a) => (r -> r') -> a (Either l r) (Either l r')
196−rightLift = right.arr
199−( ^+++ ) :: (ArrowChoice a) => (b -> c) -> a b' c' -> a (Either b b') (Either c c')
200−( +++^ ) :: (ArrowChoice a) => a b c -> (b' -> c') -> a (Either b b') (Either c c')
201−( ^+++^ ) :: (ArrowChoice a) => (b -> c) -> (b' -> c') -> a (Either b b') (Either c c')
203−l ^+++ r = leftLift l >>> right r
204−l +++^ r = left l >>> rightLift r
205−l ^+++^ r = leftLift l >>> rightLift r
207−infixr 2 ^+++, +++^, ^+++^
209( ^||| ) :: (ArrowChoice a) => (b -> d) -> a c d -> a (Either b c) d
122( ^||| ) :: (ArrowChoice a) => (b -> d) -> a c d -> a (Either b c) d
210( |||^ ) :: (ArrowChoice a) => a b d -> (c -> d) -> a (Either b c) d
123( |||^ ) :: (ArrowChoice a) => a b d -> (c -> d) -> a (Either b c) d
211( ^|||^ ) :: (ArrowChoice a) => (b -> d) -> (c -> d) -> a (Either b c) d
124( ^|||^ ) :: (ArrowChoice a) => (b -> d) -> (c -> d) -> a (Either b c) d
@@ -218,33 +131,12 @@ infixr 2 ^||| , |||^, ^|||^
219( ^&&& ) :: (Arrow a) => (b -> c) -> a b c' -> a b (c,c')
132( ^&&& ) :: (Arrow a) => (b -> c) -> a b c' -> a b (c,c')
220( &&&^ ) :: (Arrow a) => a b c -> (b -> c') -> a b (c,c')
133( &&&^ ) :: (Arrow a) => a b c -> (b -> c') -> a b (c,c')
221−( ^&&&^ ) :: (Arrow a) => (b -> c) -> (b -> c') -> a b (c,c')
223l ^&&& r = arr l &&& r
135l ^&&& r = arr l &&& r
224l &&&^ r = l &&& arr r
136l &&&^ r = l &&& arr r
225−l ^&&&^ r = arr l &&& arr r
227−infixr 3 ^&&&, &&&^, ^&&&^
229−( ^*** ) :: (Arrow a) => (b -> c) -> a b' c' -> a (b,b') (c,c')
138+infixr 3 ^&&&, &&&^
230−( ***^ ) :: (Arrow a) => a b c -> (b' -> c') -> a (b,b') (c,c')
231−( ^***^ ) :: (Arrow a) => (b -> c) -> (b' -> c') -> a (b,b') (c,c')
233−l ^*** r = arr l *** r
234−l ***^ r = l *** arr r
235−l ^***^ r = arr l *** arr r
237−infixr 3 ^***, ***^, ^***^
241−-- >>> \p -> arr (\x -> if p x the Right x else Left x)
243−-- but with p being an arrow
244−choose :: (ArrowChoice a) => a b Bool -> a b (Either b b)
245−choose checkValue = keepingTheValue checkValue >>^ select
246− where select (x,True ) = Right x
247− select (x,False ) = Left x
249-- | Converts @Right a@ into @Just a@ and @Left _@ into @Nothing@.
141-- | Converts @Right a@ into @Just a@ and @Left _@ into @Nothing@.
250choiceToMaybe :: (ArrowChoice a) => a (Either l r) (Maybe r)
142choiceToMaybe :: (ArrowChoice a) => a (Either l r) (Maybe r)
@@ -258,130 +150,15 @@ maybeToChoice = arr maybeToEither
258returnV :: (Arrow a) => c -> a x c
150returnV :: (Arrow a) => c -> a x c
259returnV = arr.const
151returnV = arr.const
261−-- | 'returnA' dropping everything
262−returnA_ :: (Arrow a) => a _b ()
263−returnA_ = returnV ()
265−-- | Wrapper for an arrow that can be evaluated im parallel. All
266−-- Arrows can be evaluated in parallel, as long as they return a
268−newtype ParallelArrow a b c = CoEval { evalParallelArrow :: a b c }
269− deriving (Eq, Ord, Show)
271−instance (Arrow a, Monoid m) => Monoid (ParallelArrow a b m) where
272− mempty = CoEval $ returnV mempty
273− (CoEval a) `mappend` (CoEval ~b) = CoEval $ a &&& b >>% mappend
275−-- | Evaluates a collection of arrows in a parallel fashion.
277−-- This is in essence a fold of '(&&&)' over the collection,
278−-- so the actual execution order and parallelity depends on the
279−-- implementation of '(&&&)' in the arrow in question.
280−-- The default implementation of '(&&&)' for example keeps the
281−-- order as given in the collection.
283−-- This function can be seen as a generalization of
284−-- 'Control.Applicative.sequenceA' to arrows or as an alternative to
285−-- a fold with 'Control.Applicative.WrappedArrow', which
286−-- substitutes the monoid with function application.
288−coEval :: (Arrow a, F.Foldable f, Monoid m) => f (a b m) -> a b m
289−coEval = evalParallelArrow . (F.foldMap CoEval)
291-- | Defines Left as failure, Right as success
153-- | Defines Left as failure, Right as success
292type FallibleArrow a input failure success = a input (Either failure success)
154type FallibleArrow a input failure success = a input (Either failure success)
294−type ReFallibleArrow a failure success success'
295− = FallibleArrow a (Either failure success) failure success'
297−-- | Wrapper for fallible arrows. Fallible arrows are all arrows that return
298−-- an Either value where left is a faliure and right is a success value.
299−newtype AlternativeArrow a input failure success
300− = TryArrow { evalAlternativeArrow :: FallibleArrow a input failure success }
303−instance (ArrowChoice a, Monoid failure)
304− => Monoid (AlternativeArrow a input failure success) where
305− mempty = TryArrow $ returnV $ Left mempty
306− (TryArrow a) `mappend` (TryArrow b)
307− = TryArrow $ a &&& b
309− -> ( (\a'' -> left (mappend a'') b') ||| Right )
312−-- | Evaluates a collection of fallible arrows, trying each one in succession.
313−-- Left values are interpreted as failures, right values as successes.
315−-- The evaluation is stopped once an arrow succeeds.
316−-- Up to that point, all failures are collected in the failure-monoid.
317−-- Note that '()' is a monoid, and thus can serve as a failure-collector if
318−-- you are uninterested in the exact failures.
320−-- This is in essence a fold of '(&&&)' over the collection, enhanced with a
321−-- little bit of repackaging, so the actual execution order depends on the
322−-- implementation of '(&&&)' in the arrow in question.
323−-- The default implementation of '(&&&)' for example keeps the
324−-- order as given in the collection.
326−tryArrows :: (ArrowChoice a, F.Foldable f, Monoid failure)
327− => f (FallibleArrow a b failure success)
328− -> FallibleArrow a b failure success
329−tryArrows = evalAlternativeArrow . (F.foldMap TryArrow)
332−liftSuccess :: (ArrowChoice a)
333− => (success -> success')
334− -> ReFallibleArrow a failure success success'
335−liftSuccess = rightLift
338liftAsSuccess :: (ArrowChoice a)
157liftAsSuccess :: (ArrowChoice a)
339 => a x success
158 => a x success
340 -> FallibleArrow a x failure success
159 -> FallibleArrow a x failure success
341liftAsSuccess a = a >>^ Right
160liftAsSuccess a = a >>^ Right
344−asFallibleArrow :: (ArrowChoice a)
346− -> FallibleArrow a x failure success
347−asFallibleArrow a = a >>^ Right
349−-- | Raises an error into a 'ReFallibleArrow' if the arrow is already in
351−liftError :: (ArrowChoice a, Monoid failure)
353− -> ReFallibleArrow a failure success success
354−liftError e = leftLift (e <>)
356−-- | Raises an error into a 'FallibleArrow', droping both the arrow input
357−-- and any previously stored error value.
358−_raiseA :: (ArrowChoice a)
360− -> FallibleArrow a x failure success
361−_raiseA e = returnV (Left e)
363−-- | Raises an empty error into a 'FallibleArrow', droping both the arrow input
364−-- and any previously stored error value.
365−_raiseAEmpty :: (ArrowChoice a, Monoid failure)
366− => FallibleArrow a x failure success
367−_raiseAEmpty = _raiseA mempty
369−-- | Raises an error into a 'ReFallibleArrow', possibly appending the new error
370−-- to an existing one
371−raiseA :: (ArrowChoice a, Monoid failure)
373− -> ReFallibleArrow a failure success success
374−raiseA e = arr $ Left.(either (<> e) (const e))
376−-- | Raises an empty error into a 'ReFallibleArrow'. If there already is an
377−-- error, nothing changes.
378−-- (Note that this function is only aequivalent to @raiseA mempty@ iff the
379−-- failure monoid follows the monoid laws.)
380−raiseAEmpty :: (ArrowChoice a, Monoid failure)
381− => ReFallibleArrow a failure success success
382−raiseAEmpty = arr (fromRight (const mempty) >>> Left)
385-- | Execute the second arrow if the first succeeds
162-- | Execute the second arrow if the first succeeds
386(>>?) :: (ArrowChoice a)
163(>>?) :: (ArrowChoice a)
387 => FallibleArrow a x failure success
164 => FallibleArrow a x failure success
@@ -410,20 +187,6 @@ a >>?^? b = a >>> Left ^|||^ b
410 -> FallibleArrow a x failure success'
187 -> FallibleArrow a x failure success'
411a ^>>? b = a ^>> Left ^||| b
188a ^>>? b = a ^>> Left ^||| b
413−-- | Execute the lifted second arrow if the lifted first arrow succeeds
414−(^>>?^) :: (ArrowChoice a)
415− => (x -> Either failure success)
416− -> (success -> success')
417− -> FallibleArrow a x failure success'
418−a ^>>?^ f = arr $ a >>> right f
420−-- | Execute the lifted second arrow if the lifted first arrow succeeds
421−(^>>?^?) :: (ArrowChoice a)
422− => (x -> Either failure success)
423− -> (success -> Either failure success')
424− -> FallibleArrow a x failure success'
425−a ^>>?^? f = a ^>> Left ^|||^ f
427-- | Execute the second, non-fallible arrow if the first arrow succeeds
190-- | Execute the second, non-fallible arrow if the first arrow succeeds
428(>>?!) :: (ArrowChoice a)
191(>>?!) :: (ArrowChoice a)
429 => FallibleArrow a x failure success
192 => FallibleArrow a x failure success
@@ -453,33 +216,9 @@ a ^>>?% f = arr a >>?^ (uncurry f)
453a >>?%? f = a >>?^? (uncurry f)
216a >>?%? f = a >>?^? (uncurry f)
455infixr 1 >>?, >>?^, >>?^?
218infixr 1 >>?, >>?^, >>?^?
456−infixr 1 ^>>?, ^>>?^, ^>>?^?, >>?!
219+infixr 1 ^>>?, >>?!
457infixr 1 >>?%, ^>>?%, >>?%?
220infixr 1 >>?%, ^>>?%, >>?%?
459−-- | Keep values that are Right, replace Left values by a constant.
460−ifFailedUse :: (ArrowChoice a) => v -> a (Either f v) v
461−ifFailedUse v = arr $ either (const v) id
463−-- | '(&&)' lifted into an arrow
464−(<&&>) :: (Arrow a) => a x Bool -> a x Bool -> a x Bool
467−-- | '(||)' lifted into an arrow
468−(<||>) :: (Arrow a) => a x Bool -> a x Bool -> a x Bool
471−-- | An equivalent of '(&&)' in a fallible arrow
472−(>&&<) :: (ArrowChoice a, Monoid f) => FallibleArrow a x f s
473− -> FallibleArrow a x f s'
474− -> FallibleArrow a x f (s,s')
475−(>&&<) = liftA2 chooseMin
477−-- | An equivalent of '(||)' in some forms of fallible arrows
478−(>||<) :: (ArrowChoice a, Monoid f, Monoid s) => FallibleArrow a x f s
479− -> FallibleArrow a x f s
480− -> FallibleArrow a x f s
481−(>||<) = liftA2 chooseMax
483-- | An arrow version of a short-circuit (<|>)
222-- | An arrow version of a short-circuit (<|>)
484ifFailedDo :: (ArrowChoice a)
223ifFailedDo :: (ArrowChoice a)
485 => FallibleArrow a x f y
224 => FallibleArrow a x f y
@@ -489,7 +228,4 @@ ifFailedDo a b = keepingTheValue a >>> repackage ^>> (b |||^ Right)
489 where repackage (x , Left _) = Left x
228 where repackage (x , Left _) = Left x
490 repackage (_ , Right y) = Right y
229 repackage (_ , Right y) = Right y
492−infixr 4 <&&>, <||>, >&&<, >||<
493infixr 1 `ifFailedDo`
231infixr 1 `ifFailedDo`