@@ -40,10 +40,7 @@ with an equivalent return value.
4040module Text.Pandoc.Readers.Odt.Arrows.Utils where
4141
4242import Control.Arrow
43−import Control.Monad ( join, MonadPlus(..) )
44−
45−import qualified Data.Foldable as F
46−import Data.Monoid
43+import Control.Monad ( join )
4744
4845import Text.Pandoc.Readers.Odt.Generic.Fallible
4946import Text.Pandoc.Readers.Odt.Generic.Utils
@@ -63,12 +60,6 @@ and5 :: (Arrow a)
6360and6 :: (Arrow a)
6461 => a b c0->a b c1->a b c2->a b c3->a b c4->a b c5
6562 -> a b (c0,c1,c2,c3,c4,c5 )
66−and7 :: (Arrow a)
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 )
69−and8 :: (Arrow a)
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)
7263
7364and3 a b c = (and2 a b ) &&& c
7465 >>^ \((z,y ) , x) -> (z,y,x )
@@ -78,10 +69,6 @@ and5 a b c d e = (and4 a b c d ) &&& e
7869 >>^ \((z,y,x,w ) , v) -> (z,y,x,w,v )
7970and6 a b c d e f = (and5 a b c d e ) &&& f
8071 >>^ \((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)
8572
8673liftA2 :: (Arrow a) => (x -> y -> z) -> a b x -> a b y -> a b z
8774liftA2 f a b = a &&& b >>^ uncurry f
@@ -98,19 +85,11 @@ liftA5 :: (Arrow a) => (z->y->x->w->v -> r)
9885liftA6 :: (Arrow a) => (z->y->x->w->v->u -> r)
9986 -> a b z->a b y->a b x->a b w->a b v->a b u
10087 -> a b r
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
103− -> a b r
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
106− -> a b r
10788
10889liftA3 fun a b c = and3 a b c >>^ uncurry3 fun
10990liftA4 fun a b c d = and4 a b c d >>^ uncurry4 fun
11091liftA5 fun a b c d e = and5 a b c d e >>^ uncurry5 fun
11192liftA6 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
11493
11594liftA :: (Arrow a) => (y -> z) -> a b y -> a b z
11695liftA fun a = a >>^ fun
@@ -124,28 +103,12 @@ liftA fun a = a >>^ fun
124103duplicate :: (Arrow a) => a b (b,b)
125104duplicate = arr $ join (,)
126105
127−-- | Lifts the combination of two values into an arrow.
128−joinOn :: (Arrow a) => (x -> y -> z) -> a (x,y) z
129−joinOn = arr.uncurry
130−
131106-- | Applies a function to the uncurried result-pair of an arrow-application.
132107-- (The %-symbol was chosen to evoke an association with pairs.)
133108(>>%) :: (Arrow a) => a x (b,c) -> (b -> c -> d) -> a x d
134109a >>% f = a >>^ uncurry f
135110
136−-- | '(>>%)' with its arguments flipped
137−(%<<) :: (Arrow a) => (b -> c -> d) -> a x (b,c) -> a x d
138−(%<<) = flip (>>%)
139−
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
143−
144−-- | Precomposition with an uncurried function (right to left variant)
145−(<<%) :: (Arrow a) => a d r -> (b -> c -> d) -> a (b,c) r
146−(<<%) = flip (%>>)
147−
148−infixr 2 >>%, %<<, %>>, <<%
111+infixr 2 >>%
149112
150113
151114-- | Duplicate a value and apply an arrow to the second instance.
@@ -156,56 +119,6 @@ infixr 2 >>%, %<<, %>>, <<%
156119keepingTheValue :: (Arrow a) => a b c -> a b (b,c)
157120keepingTheValue a = returnA &&& a
158121
159−-- | Duplicate a value and apply an arrow to the first instance.
160−-- Aequivalent to
161−-- > \a -> duplicate >>> first a
162−-- or
163−-- > \a -> a &&& returnA
164−keepingTheValue' :: (Arrow a) => a b c -> a b (c,b)
165−keepingTheValue' a = a &&& returnA
166−
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.
174−--
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
182−
183−infixr 2 >>>=
184−
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
189−
190−-- | Left-compose with a pure function
191−leftLift :: (ArrowChoice a) => (l -> l') -> a (Either l r) (Either l' r)
192−leftLift = left.arr
193−
194−-- | Right-compose with a pure function
195−rightLift :: (ArrowChoice a) => (r -> r') -> a (Either l r) (Either l r')
196−rightLift = right.arr
197−
198−
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')
202−
203−l ^+++ r = leftLift l >>> right r
204−l +++^ r = left l >>> rightLift r
205−l ^+++^ r = leftLift l >>> rightLift r
206−
207−infixr 2 ^+++, +++^, ^+++^
208−
209122( ^||| ) :: (ArrowChoice a) => (b -> d) -> a c d -> a (Either b c) d
210123( |||^ ) :: (ArrowChoice a) => a b d -> (c -> d) -> a (Either b c) d
211124( ^|||^ ) :: (ArrowChoice a) => (b -> d) -> (c -> d) -> a (Either b c) d
@@ -218,33 +131,12 @@ infixr 2 ^||| , |||^, ^|||^
218131
219132( ^&&& ) :: (Arrow a) => (b -> c) -> a b c' -> a b (c,c')
220133( &&&^ ) :: (Arrow a) => a b c -> (b -> c') -> a b (c,c')
221−( ^&&&^ ) :: (Arrow a) => (b -> c) -> (b -> c') -> a b (c,c')
222134
223135l ^&&& r = arr l &&& r
224136l &&&^ r = l &&& arr r
225−l ^&&&^ r = arr l &&& arr r
226−
227−infixr 3 ^&&&, &&&^, ^&&&^
228137
229−( ^*** ) :: (Arrow a) => (b -> c) -> a b' c' -> a (b,b') (c,c')
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')
138+infixr 3 ^&&&, &&&^
232139
233−l ^*** r = arr l *** r
234−l ***^ r = l *** arr r
235−l ^***^ r = arr l *** arr r
236−
237−infixr 3 ^***, ***^, ^***^
238−
239−-- | A version of
240−--
241−-- >>> \p -> arr (\x -> if p x the Right x else Left x)
242−--
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
248140
249141-- | Converts @Right a@ into @Just a@ and @Left _@ into @Nothing@.
250142choiceToMaybe :: (ArrowChoice a) => a (Either l r) (Maybe r)
@@ -258,130 +150,15 @@ maybeToChoice = arr maybeToEither
258150returnV :: (Arrow a) => c -> a x c
259151returnV = arr.const
260152
261−-- | 'returnA' dropping everything
262−returnA_ :: (Arrow a) => a _b ()
263−returnA_ = returnV ()
264−
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
267−-- monoid.
268−newtype ParallelArrow a b c = CoEval { evalParallelArrow :: a b c }
269− deriving (Eq, Ord, Show)
270−
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
274−
275−-- | Evaluates a collection of arrows in a parallel fashion.
276−--
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.
282−--
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.
287−--
288−coEval :: (Arrow a, F.Foldable f, Monoid m) => f (a b m) -> a b m
289−coEval = evalParallelArrow . (F.foldMap CoEval)
290−
291153-- | Defines Left as failure, Right as success
292154type FallibleArrow a input failure success = a input (Either failure success)
293155
294−type ReFallibleArrow a failure success success'
295− = FallibleArrow a (Either failure success) failure success'
296−
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 }
301−
302−
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
308− >>^ \(a',~b')
309− -> ( (\a'' -> left (mappend a'') b') ||| Right )
310− a'
311−
312−-- | Evaluates a collection of fallible arrows, trying each one in succession.
313−-- Left values are interpreted as failures, right values as successes.
314−--
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.
319−--
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.
325−--
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)
330−
331−--
332−liftSuccess :: (ArrowChoice a)
333− => (success -> success')
334− -> ReFallibleArrow a failure success success'
335−liftSuccess = rightLift
336−
337156--
338157liftAsSuccess :: (ArrowChoice a)
339158 => a x success
340159 -> FallibleArrow a x failure success
341160liftAsSuccess a = a >>^ Right
342161
343−--
344−asFallibleArrow :: (ArrowChoice a)
345− => a x success
346− -> FallibleArrow a x failure success
347−asFallibleArrow a = a >>^ Right
348−
349−-- | Raises an error into a 'ReFallibleArrow' if the arrow is already in
350−-- "error mode"
351−liftError :: (ArrowChoice a, Monoid failure)
352− => failure
353− -> ReFallibleArrow a failure success success
354−liftError e = leftLift (e <>)
355−
356−-- | Raises an error into a 'FallibleArrow', droping both the arrow input
357−-- and any previously stored error value.
358−_raiseA :: (ArrowChoice a)
359− => failure
360− -> FallibleArrow a x failure success
361−_raiseA e = returnV (Left e)
362−
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
368−
369−-- | Raises an error into a 'ReFallibleArrow', possibly appending the new error
370−-- to an existing one
371−raiseA :: (ArrowChoice a, Monoid failure)
372− => failure
373− -> ReFallibleArrow a failure success success
374−raiseA e = arr $ Left.(either (<> e) (const e))
375−
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)
383−
384−
385162-- | Execute the second arrow if the first succeeds
386163(>>?) :: (ArrowChoice a)
387164 => FallibleArrow a x failure success
@@ -410,20 +187,6 @@ a >>?^? b = a >>> Left ^|||^ b
410187 -> FallibleArrow a x failure success'
411188a ^>>? b = a ^>> Left ^||| b
412189
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
419−
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
426−
427190-- | Execute the second, non-fallible arrow if the first arrow succeeds
428191(>>?!) :: (ArrowChoice a)
429192 => FallibleArrow a x failure success
@@ -453,33 +216,9 @@ a ^>>?% f = arr a >>?^ (uncurry f)
453216a >>?%? f = a >>?^? (uncurry f)
454217
455218infixr 1 >>?, >>?^, >>?^?
456−infixr 1 ^>>?, ^>>?^, ^>>?^?, >>?!
219+infixr 1 ^>>?, >>?!
457220infixr 1 >>?%, ^>>?%, >>?%?
458221
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
462−
463−-- | '(&&)' lifted into an arrow
464−(<&&>) :: (Arrow a) => a x Bool -> a x Bool -> a x Bool
465−(<&&>) = liftA2 (&&)
466−
467−-- | '(||)' lifted into an arrow
468−(<||>) :: (Arrow a) => a x Bool -> a x Bool -> a x Bool
469−(<||>) = liftA2 (||)
470−
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
476−
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
482−
483222-- | An arrow version of a short-circuit (<|>)
484223ifFailedDo :: (ArrowChoice a)
485224 => FallibleArrow a x f y
@@ -489,7 +228,4 @@ ifFailedDo a b = keepingTheValue a >>> repackage ^>> (b |||^ Right)
489228 where repackage (x , Left _) = Left x
490229 repackage (_ , Right y) = Right y
491230
492−infixr 4 <&&>, <||>, >&&<, >||<
493231infixr 1 `ifFailedDo`
494−
495−