module Text.ParserCombinators.Poly.Result
  ( -- * The parsing result type
    Result(..)	-- A parsing result type, with Success, Failure, and Commitment.
  , resultToEither
  ) where


-- | A return type like Either, that distinguishes not only between
--   right and wrong answers, but also has commitment, so that a failure
--   cannot be undone.  This should only be used for writing very primitive
--   parsers - really it is an internal detail of the library.
--   The z type is the remaining unconsumed input.
data Result z a = Success   z a
                | Failure   z String
                | Committed (Result z a)

instance Functor (Result z) where
    fmap :: (a -> b) -> Result z a -> Result z b
fmap a -> b
f (Success z
z a
a) = z -> b -> Result z b
forall z a. z -> a -> Result z a
Success z
z (a -> b
f a
a)
    fmap a -> b
f (Failure z
z String
e) = z -> String -> Result z b
forall z a. z -> String -> Result z a
Failure z
z String
e
    fmap a -> b
f (Committed Result z a
r) = Result z b -> Result z b
forall z a. Result z a -> Result z a
Committed ((a -> b) -> Result z a -> Result z b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f Result z a
r)

-- | Convert a Result to an Either, paired with the remaining unconsumed input.
resultToEither :: Result z a -> (Either String a, z)
resultToEither :: Result z a -> (Either String a, z)
resultToEither (Success z
z a
a)  =  (a -> Either String a
forall a b. b -> Either a b
Right a
a, z
z)
resultToEither (Failure z
z String
e)  =  (String -> Either String a
forall a b. a -> Either a b
Left String
e, z
z)
resultToEither (Committed Result z a
r)  =  Result z a -> (Either String a, z)
forall z a. Result z a -> (Either String a, z)
resultToEither Result z a
r

------------------------------------------------------------------------