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

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

Data types and utilities representing failure. Most of it is based on the
"Either" type in its usual configuration (left represents failure).
-}

module Text.Pandoc.Readers.ODT.Generic.Fallible
  ( Failure
  , Fallible
  , chooseMax
  , chooseMaxWith
  ) where

-- | Default for now. Will probably become a class at some point.
type Failure = ()

type Fallible a = Either Failure a

-- | If either of the values represents a  non-error, the result is a
-- (possibly combined) non-error. If both values represent an error, an error
-- is returned.
chooseMax :: (Monoid a, Monoid b) => Either a b -> Either a b -> Either a b
chooseMax :: forall a b.
(Monoid a, Monoid b) =>
Either a b -> Either a b -> Either a b
chooseMax = (b -> b -> b) -> Either a b -> Either a b -> Either a b
forall a b.
Monoid a =>
(b -> b -> b) -> Either a b -> Either a b -> Either a b
chooseMaxWith b -> b -> b
forall a. Monoid a => a -> a -> a
mappend

-- | If either of the values represents a non-error, the result is a
-- (possibly combined) non-error. If both values represent an error, an error
-- is returned.
chooseMaxWith :: (Monoid a) => (b -> b -> b)
                            -> Either a b
                            -> Either a b
                            -> Either a b
chooseMaxWith :: forall a b.
Monoid a =>
(b -> b -> b) -> Either a b -> Either a b -> Either a b
chooseMaxWith b -> b -> b
(><) (Right b
a) (Right b
b) = b -> Either a b
forall a b. b -> Either a b
Right (b -> Either a b) -> b -> Either a b
forall a b. (a -> b) -> a -> b
$ b
a b -> b -> b
>< b
b
chooseMaxWith  b -> b -> b
_   (Left  a
a) (Left  a
b) = a -> Either a b
forall a b. a -> Either a b
Left  (a -> Either a b) -> a -> Either a b
forall a b. (a -> b) -> a -> b
$ a
a a -> a -> a
forall a. Monoid a => a -> a -> a
`mappend` a
b
chooseMaxWith  b -> b -> b
_   (Right b
a)     Either a b
_     = b -> Either a b
forall a b. b -> Either a b
Right b
a
chooseMaxWith  b -> b -> b
_       Either a b
_     (Right b
b) = b -> Either a b
forall a b. b -> Either a b
Right b
b