    {-# LANGUAGE CPP #-}
    {-# LANGUAGE DeriveFunctor #-}

    -- Note: This module was copied from cabal-install.

    -- | A progress monad, which we use to report failure and logging from
    -- otherwise pure code.
    module Distribution.Utils.Progress
      ( Progress
      , stepProgress
      , failProgress
      , foldProgress
      ) where

    import Distribution.Compat.Prelude
    import Prelude ()

    import qualified Data.Monoid as Mon

    -- | A type to represent the unfolding of an expensive long running
    -- calculation that may fail (or maybe not expensive, but complicated!)
    -- We may get intermediate steps before the final
    -- result which may be used to indicate progress and\/or logging messages.
    --
    -- TODO: Apply Codensity to avoid left-associativity problem.
    -- See http://comonad.com/reader/2011/free-monads-for-less/ and
    -- http://blog.ezyang.com/2012/01/problem-set-the-codensity-transformation/
    data Progress step fail done
      = Step step (Progress step fail done)
      | Fail fail
      | Done done
      deriving ((forall a b.
     (a -> b) -> Progress step fail a -> Progress step fail b)
    -> (forall a b. a -> Progress step fail b -> Progress step fail a)
    -> Functor (Progress step fail)
    forall a b. a -> Progress step fail b -> Progress step fail a
    forall a b.
    (a -> b) -> Progress step fail a -> Progress step fail b
    forall step fail a b.
    a -> Progress step fail b -> Progress step fail a
    forall step fail a b.
    (a -> b) -> Progress step fail a -> Progress step fail b
    forall (f :: * -> *).
    (forall a b. (a -> b) -> f a -> f b)
    -> (forall a b. a -> f b -> f a) -> Functor f
    $cfmap :: forall step fail a b.
    (a -> b) -> Progress step fail a -> Progress step fail b
    fmap :: forall a b.
    (a -> b) -> Progress step fail a -> Progress step fail b
    $c<$ :: forall step fail a b.
    a -> Progress step fail b -> Progress step fail a
    <$ :: forall a b. a -> Progress step fail b -> Progress step fail a
    Functor)

    -- | Emit a step and then continue.
    stepProgress :: step -> Progress step fail ()
    stepProgress :: forall step fail. step -> Progress step fail ()
    stepProgress step
    step = step -> Progress step fail () -> Progress step fail ()
    forall step fail done.
    step -> Progress step fail done -> Progress step fail done
    Step step
    step (() -> Progress step fail ()
    forall step fail done. done -> Progress step fail done
    Done ())

    -- | Fail the computation.
    failProgress :: fail -> Progress step fail done
    failProgress :: forall fail step done. fail -> Progress step fail done
    failProgress fail
    err = fail -> Progress step fail done
    forall step fail done. fail -> Progress step fail done
    Fail fail
    err

    -- | Consume a 'Progress' calculation. Much like 'foldr' for lists but with two
    -- base cases, one for a final result and one for failure.
    --
    -- Eg to convert into a simple 'Either' result use:
    --
    -- > foldProgress (flip const) Left Right
    foldProgress
      :: (step -> a -> a)
      -> (fail -> a)
      -> (done -> a)
      -> Progress step fail done
      -> a
    foldProgress :: forall step a fail done.
    (step -> a -> a)
    -> (fail -> a) -> (done -> a) -> Progress step fail done -> a
    foldProgress step -> a -> a
    step fail -> a
    err done -> a
    done = Progress step fail done -> a
    fold
      where
        fold :: Progress step fail done -> a
    fold (Step step
    s Progress step fail done
    p) = step -> a -> a
    step step
    s (Progress step fail done -> a
    fold Progress step fail done
    p)
        fold (Fail fail
    f) = fail -> a
    err fail
    f
        fold (Done done
    r) = done -> a
    done done
    r

    instance Monad (Progress step fail) where
      return :: forall a. a -> Progress step fail a
    return = a -> Progress step fail a
    forall a. a -> Progress step fail a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure
      Progress step fail a
    p >>= :: forall a b.
    Progress step fail a
    -> (a -> Progress step fail b) -> Progress step fail b
    >>= a -> Progress step fail b
    f = (step -> Progress step fail b -> Progress step fail b)
    -> (fail -> Progress step fail b)
    -> (a -> Progress step fail b)
    -> Progress step fail a
    -> Progress step fail b
    forall step a fail done.
    (step -> a -> a)
    -> (fail -> a) -> (done -> a) -> Progress step fail done -> a
    foldProgress step -> Progress step fail b -> Progress step fail b
    forall step fail done.
    step -> Progress step fail done -> Progress step fail done
    Step fail -> Progress step fail b
    forall step fail done. fail -> Progress step fail done
    Fail a -> Progress step fail b
    f Progress step fail a
    p

    instance Applicative (Progress step fail) where
      pure :: forall a. a -> Progress step fail a
    pure a
    a = a -> Progress step fail a
    forall step fail done. done -> Progress step fail done
    Done a
    a
      Progress step fail (a -> b)
    p <*> :: forall a b.
    Progress step fail (a -> b)
    -> Progress step fail a -> Progress step fail b
    <*> Progress step fail a
    x = (step -> Progress step fail b -> Progress step fail b)
    -> (fail -> Progress step fail b)
    -> ((a -> b) -> Progress step fail b)
    -> Progress step fail (a -> b)
    -> Progress step fail b
    forall step a fail done.
    (step -> a -> a)
    -> (fail -> a) -> (done -> a) -> Progress step fail done -> a
    foldProgress step -> Progress step fail b -> Progress step fail b
    forall step fail done.
    step -> Progress step fail done -> Progress step fail done
    Step fail -> Progress step fail b
    forall step fail done. fail -> Progress step fail done
    Fail (((a -> b) -> Progress step fail a -> Progress step fail b)
    -> Progress step fail a -> (a -> b) -> Progress step fail b
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip (a -> b) -> Progress step fail a -> Progress step fail b
    forall a b.
    (a -> b) -> Progress step fail a -> Progress step fail b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Progress step fail a
    x) Progress step fail (a -> b)
    p

    instance Monoid fail => Alternative (Progress step fail) where
      empty :: forall a. Progress step fail a
    empty = fail -> Progress step fail a
    forall step fail done. fail -> Progress step fail done
    Fail fail
    forall a. Monoid a => a
    Mon.mempty
      Progress step fail a
    p <|> :: forall a.
    Progress step fail a
    -> Progress step fail a -> Progress step fail a
    <|> Progress step fail a
    q = (step -> Progress step fail a -> Progress step fail a)
    -> (fail -> Progress step fail a)
    -> (a -> Progress step fail a)
    -> Progress step fail a
    -> Progress step fail a
    forall step a fail done.
    (step -> a -> a)
    -> (fail -> a) -> (done -> a) -> Progress step fail done -> a
    foldProgress step -> Progress step fail a -> Progress step fail a
    forall step fail done.
    step -> Progress step fail done -> Progress step fail done
    Step (Progress step fail a -> fail -> Progress step fail a
    forall a b. a -> b -> a
    const Progress step fail a
    q) a -> Progress step fail a
    forall step fail done. done -> Progress step fail done
    Done Progress step fail a
    p