packages feed

exitcode 0.2.0.0 → 0.3.0.0

raw patch · 21 files changed

+2588/−1331 lines, 21 filesdep +comonaddep +deepseqdep +naturaldep −QuickCheckdep −checkersdep −hedgehogdep ~mtldep ~processdep ~semigroupoidssetup-changedPVP ok

version bump matches the API change (PVP)

Dependencies added: comonad, deepseq, natural, tasty-bench

Dependencies removed: QuickCheck, checkers, hedgehog, semigroups, tasty, tasty-hedgehog, tasty-hunit, tasty-quickcheck

Dependency ranges changed: mtl, process, semigroupoids, transformers

API changes (from Hackage documentation)

- Control.Exitcode: _ExitFailure :: forall (f :: Type -> Type) e e'. Traversable f => Traversal (ExitcodeT f e ()) (ExitcodeT f e' ()) (e, Int) (e', Int)
- Control.Exitcode: _ExitFailureError :: forall (f :: Type -> Type) e a e'. Traversable f => Traversal (ExitcodeT f e a) (ExitcodeT f e' a) e e'
- Control.Exitcode: _ExitSuccess :: forall e a a' p f. (Choice p, Applicative f) => p a (f a') -> p (Exitcode e a) (f (Exitcode e a'))
- Control.Exitcode: _Exitcode1 :: forall a a' f. Functor f => (a -> f a') -> Exitcode1 a -> f (Exitcode1 a')
- Control.Exitcode: _ExitcodeInt :: forall (f :: Type -> Type) (f' :: Type -> Type). (Functor f, Functor f') => Iso (ExitcodeT0 f) (ExitcodeT0 f') (f Int) (f' Int)
- Control.Exitcode: _ExitcodeInt' :: forall (f :: Type -> Type). Traversable f => Traversal' (ExitcodeT0 f) Int
- Control.Exitcode: data ExitcodeT (f :: Type -> Type) e a
- Control.Exitcode: embedExitcode :: forall (g :: Type -> Type) f e a. Functor g => (forall x. () => f x -> ExitcodeT g e x) -> ExitcodeT f e a -> ExitcodeT g e a
- Control.Exitcode: exitCode :: forall (f :: Type -> Type) (g :: Type -> Type). (Functor f, Functor g) => Iso (f ExitCode) (g ExitCode) (ExitcodeT0 (MaybeT f)) (ExitcodeT0 (MaybeT g))
- Control.Exitcode: exitcode1 :: forall (f :: Type -> Type) a. Applicative f => Int -> a -> ExitcodeT1 f a
- Control.Exitcode: exitcodeValue :: forall (f :: Type -> Type) e a. Applicative f => e -> Int -> a -> ExitcodeT f e a
- Control.Exitcode: exitcodeValue0 :: forall (f :: Type -> Type). Applicative f => Int -> ExitcodeT0 f
- Control.Exitcode: exitfailure :: forall (f :: Type -> Type) e. Applicative f => e -> Int -> ExitcodeT f e ()
- Control.Exitcode: exitfailure0 :: forall (f :: Type -> Type). Applicative f => Int -> ExitcodeT0 f
- Control.Exitcode: exitfailureNeg1 :: forall (f :: Type -> Type) e a. Applicative f => e -> Int -> ExitcodeT f e a
- Control.Exitcode: exitsuccess :: forall (f :: Type -> Type) a e. Applicative f => a -> ExitcodeT f e a
- Control.Exitcode: exitsuccess0 :: forall (f :: Type -> Type) e. Applicative f => ExitcodeT f e ()
- Control.Exitcode: fromExitCode :: Functor f => f ExitCode -> ExitcodeT0 f
- Control.Exitcode: fromExitCode' :: ExitCode -> Exitcode0
- Control.Exitcode: hoistExitcode :: (forall x. () => f x -> g x) -> ExitcodeT f e a -> ExitcodeT g e a
- Control.Exitcode: instance (Data.Functor.Classes.Eq1 f, GHC.Classes.Eq e) => Data.Functor.Classes.Eq1 (Control.Exitcode.ExitcodeT f e)
- Control.Exitcode: instance (Data.Functor.Classes.Eq1 f, GHC.Classes.Eq e, GHC.Classes.Eq a) => GHC.Classes.Eq (Control.Exitcode.ExitcodeT f e a)
- Control.Exitcode: instance (Data.Functor.Classes.Ord1 f, GHC.Classes.Ord e) => Data.Functor.Classes.Ord1 (Control.Exitcode.ExitcodeT f e)
- Control.Exitcode: instance (Data.Functor.Classes.Ord1 f, GHC.Classes.Ord e, GHC.Classes.Ord a) => GHC.Classes.Ord (Control.Exitcode.ExitcodeT f e a)
- Control.Exitcode: instance (Data.Functor.Classes.Show1 f, GHC.Show.Show e) => Data.Functor.Classes.Show1 (Control.Exitcode.ExitcodeT f e)
- Control.Exitcode: instance (Data.Functor.Classes.Show1 f, GHC.Show.Show e, GHC.Show.Show a) => GHC.Show.Show (Control.Exitcode.ExitcodeT f e a)
- Control.Exitcode: instance (GHC.Base.Monoid a, GHC.Base.Applicative f) => GHC.Base.Monoid (Control.Exitcode.ExitcodeT f e a)
- Control.Exitcode: instance (GHC.Base.Semigroup a, GHC.Base.Applicative f) => GHC.Base.Semigroup (Control.Exitcode.ExitcodeT f e a)
- Control.Exitcode: instance Control.Monad.Cont.Class.MonadCont f => Control.Monad.Cont.Class.MonadCont (Control.Exitcode.ExitcodeT f e)
- Control.Exitcode: instance Control.Monad.Error.Class.MonadError e f => Control.Monad.Error.Class.MonadError e (Control.Exitcode.ExitcodeT f e')
- Control.Exitcode: instance Control.Monad.IO.Class.MonadIO f => Control.Monad.IO.Class.MonadIO (Control.Exitcode.ExitcodeT f e)
- Control.Exitcode: instance Control.Monad.RWS.Class.MonadRWS r w s f => Control.Monad.RWS.Class.MonadRWS r w s (Control.Exitcode.ExitcodeT f e)
- Control.Exitcode: instance Control.Monad.Reader.Class.MonadReader r f => Control.Monad.Reader.Class.MonadReader r (Control.Exitcode.ExitcodeT f e)
- Control.Exitcode: instance Control.Monad.State.Class.MonadState s f => Control.Monad.State.Class.MonadState s (Control.Exitcode.ExitcodeT f e)
- Control.Exitcode: instance Control.Monad.Writer.Class.MonadWriter w f => Control.Monad.Writer.Class.MonadWriter w (Control.Exitcode.ExitcodeT f e)
- Control.Exitcode: instance Data.Foldable.Foldable f => Data.Bifoldable.Bifoldable (Control.Exitcode.ExitcodeT f)
- Control.Exitcode: instance Data.Foldable.Foldable f => Data.Foldable.Foldable (Control.Exitcode.ExitcodeT f e)
- Control.Exitcode: instance Data.Functor.Extend.Extend f => Data.Functor.Extend.Extend (Control.Exitcode.ExitcodeT f e)
- Control.Exitcode: instance Data.Traversable.Traversable f => Data.Bitraversable.Bitraversable (Control.Exitcode.ExitcodeT f)
- Control.Exitcode: instance Data.Traversable.Traversable f => Data.Traversable.Traversable (Control.Exitcode.ExitcodeT f e)
- Control.Exitcode: instance GHC.Base.Functor f => Data.Bifunctor.Bifunctor (Control.Exitcode.ExitcodeT f)
- Control.Exitcode: instance GHC.Base.Functor f => GHC.Base.Functor (Control.Exitcode.ExitcodeT f e)
- Control.Exitcode: instance GHC.Base.Monad f => Data.Functor.Alt.Alt (Control.Exitcode.ExitcodeT f e)
- Control.Exitcode: instance GHC.Base.Monad f => Data.Functor.Bind.Class.Apply (Control.Exitcode.ExitcodeT f e)
- Control.Exitcode: instance GHC.Base.Monad f => Data.Functor.Bind.Class.Bind (Control.Exitcode.ExitcodeT f e)
- Control.Exitcode: instance GHC.Base.Monad f => GHC.Base.Applicative (Control.Exitcode.ExitcodeT f e)
- Control.Exitcode: instance GHC.Base.Monad f => GHC.Base.Monad (Control.Exitcode.ExitcodeT f e)
- Control.Exitcode: liftExitFailureNeg1 :: Functor f => f (e, Int) -> ExitcodeT f e a
- Control.Exitcode: liftExitcode :: Functor f => f a -> ExitcodeT f e a
- Control.Exitcode: liftExitcodeFailure :: Functor f => f (e, Int) -> a -> ExitcodeT f e a
- Control.Exitcode: liftExitcodeFailure0 :: Functor f => f Int -> ExitcodeT0 f
- Control.Exitcode: liftTryExitcode :: Exception e' => IO a -> ExitcodeT (ExceptT e' IO) e a
- Control.Exitcode: maybeExitcode :: Exitcode0 -> Maybe Int
- Control.Exitcode: maybeExitcodeT :: Functor f => ExitcodeT f e a -> f (Maybe Int)
- Control.Exitcode: runExitcode :: Exitcode e a -> Either (e, Int) a
- Control.Exitcode: runExitcode1 :: Exitcode1 a -> Either (a, Int) a
- Control.Exitcode: runExitcodeT :: ExitcodeT f e a -> f (Either (e, Int) a)
- Control.Exitcode: runExitcodeT1 :: ExitcodeT1 f a -> f (Either (a, Int) a)
- Control.Exitcode: tryExitcode :: Exception e' => ExitcodeT IO e a -> ExitcodeT (ExceptT e' IO) e a
- Control.Exitcode: type Exitcode e a = ExitcodeT Identity e a
- Control.Exitcode: type Exitcode0 = Exitcode () ()
- Control.Exitcode: type Exitcode1 a = ExitcodeT1 Identity a
- Control.Exitcode: type ExitcodeT0 (f :: Type -> Type) = ExitcodeT f () ()
- Control.Exitcode: type ExitcodeT1 (f :: Type -> Type) a = ExitcodeT f a a
+ Control.Exitcode.Exitcode: Exitcode :: f (Either (e, NotZero) a) -> Exitcode e (f :: Type -> Type) a
+ Control.Exitcode.Exitcode: ExitcodeBifunctor :: Exitcode e f a -> ExitcodeBifunctor (f :: Type -> Type) e a
+ Control.Exitcode.Exitcode: _ExitFailure :: forall (f :: Type -> Type) e a. Traversable f => Prism' (Exitcode e f a) (f (e, NotZero))
+ Control.Exitcode.Exitcode: _ExitFailure' :: forall e a e' p f. (Choice p, Applicative f) => p (e, NotZero) (f (e', NotZero)) -> p (Exitcode' e a) (f (Exitcode' e' a))
+ Control.Exitcode.Exitcode: _ExitFailureCode :: forall (f :: Type -> Type) e a. Traversable f => Traversal' (Exitcode e f a) (f NotZero)
+ Control.Exitcode.Exitcode: _ExitFailureCode' :: forall e a f. Applicative f => (NotZero -> f NotZero) -> Exitcode' e a -> f (Exitcode' e a)
+ Control.Exitcode.Exitcode: _ExitFailureValue :: forall (f :: Type -> Type) e a. Traversable f => Traversal' (Exitcode e f a) (f e)
+ Control.Exitcode.Exitcode: _ExitFailureValue' :: forall e a e' f. Applicative f => (e -> f e') -> Exitcode' e a -> f (Exitcode' e' a)
+ Control.Exitcode.Exitcode: _ExitSuccess :: forall (f :: Type -> Type) e a. Traversable f => Prism' (Exitcode e f a) (f a)
+ Control.Exitcode.Exitcode: _ExitSuccess' :: forall e a a' p f. (Choice p, Applicative f) => p a (f a') -> p (Exitcode' e a) (f (Exitcode' e a'))
+ Control.Exitcode.Exitcode: _Exitcode1 :: forall a a' f. Functor f => (a -> f a') -> Exitcode' a a -> f (Exitcode' a' a')
+ Control.Exitcode.Exitcode: _Exitcode1' :: forall (f :: Type -> Type) a. Traversable f => Traversal' (Exitcode a f a) (f a)
+ Control.Exitcode.Exitcode: bimapExitcode :: forall (f :: Type -> Type) e e' a a'. Functor f => (e -> e') -> (a -> a') -> Exitcode e f a -> Exitcode e' f a'
+ Control.Exitcode.Exitcode: embedExitcode :: forall (g :: Type -> Type) f e a. Functor g => (forall x. () => f x -> Exitcode e g x) -> Exitcode e f a -> Exitcode e g a
+ Control.Exitcode.Exitcode: exitCode :: forall (f :: Type -> Type) (g :: Type -> Type). (Functor f, Functor g) => Iso (f ExitCode) (g ExitCode) (Exitcode () (MaybeT f) ()) (Exitcode () (MaybeT g) ())
+ Control.Exitcode.Exitcode: fromExitCode :: Functor f => f ExitCode -> Exitcode () f ()
+ Control.Exitcode.Exitcode: fromExitCode' :: ExitCode -> Exitcode' () ()
+ Control.Exitcode.Exitcode: hoistExitcode :: (forall x. () => f x -> g x) -> Exitcode e f a -> Exitcode e g a
+ Control.Exitcode.Exitcode: instance (Control.DeepSeq.NFData1 f, Control.DeepSeq.NFData e) => Control.DeepSeq.NFData1 (Control.Exitcode.Exitcode.Exitcode e f)
+ Control.Exitcode.Exitcode: instance (Control.DeepSeq.NFData1 f, Control.DeepSeq.NFData e) => Control.DeepSeq.NFData1 (Control.Exitcode.Exitcode.ExitcodeBifunctor f e)
+ Control.Exitcode.Exitcode: instance (Control.DeepSeq.NFData1 f, Control.DeepSeq.NFData e, Control.DeepSeq.NFData a) => Control.DeepSeq.NFData (Control.Exitcode.Exitcode.Exitcode e f a)
+ Control.Exitcode.Exitcode: instance (Control.DeepSeq.NFData1 f, Control.DeepSeq.NFData e, Control.DeepSeq.NFData a) => Control.DeepSeq.NFData (Control.Exitcode.Exitcode.ExitcodeBifunctor f e a)
+ Control.Exitcode.Exitcode: instance (Data.Functor.Classes.Eq1 f, GHC.Classes.Eq e) => Data.Functor.Classes.Eq1 (Control.Exitcode.Exitcode.Exitcode e f)
+ Control.Exitcode.Exitcode: instance (Data.Functor.Classes.Eq1 f, GHC.Classes.Eq e) => Data.Functor.Classes.Eq1 (Control.Exitcode.Exitcode.ExitcodeBifunctor f e)
+ Control.Exitcode.Exitcode: instance (Data.Functor.Classes.Ord1 f, GHC.Classes.Ord e) => Data.Functor.Classes.Ord1 (Control.Exitcode.Exitcode.Exitcode e f)
+ Control.Exitcode.Exitcode: instance (Data.Functor.Classes.Ord1 f, GHC.Classes.Ord e) => Data.Functor.Classes.Ord1 (Control.Exitcode.Exitcode.ExitcodeBifunctor f e)
+ Control.Exitcode.Exitcode: instance (Data.Functor.Classes.Show1 f, GHC.Show.Show e) => Data.Functor.Classes.Show1 (Control.Exitcode.Exitcode.Exitcode e f)
+ Control.Exitcode.Exitcode: instance (Data.Functor.Classes.Show1 f, GHC.Show.Show e) => Data.Functor.Classes.Show1 (Control.Exitcode.Exitcode.ExitcodeBifunctor f e)
+ Control.Exitcode.Exitcode: instance (GHC.Base.Monoid a, GHC.Base.Monad f) => GHC.Base.Monoid (Control.Exitcode.Exitcode.Exitcode e f a)
+ Control.Exitcode.Exitcode: instance (GHC.Base.Monoid a, GHC.Base.Monad f) => GHC.Base.Monoid (Control.Exitcode.Exitcode.ExitcodeBifunctor f e a)
+ Control.Exitcode.Exitcode: instance (GHC.Base.Semigroup a, GHC.Base.Monad f) => GHC.Base.Semigroup (Control.Exitcode.Exitcode.Exitcode e f a)
+ Control.Exitcode.Exitcode: instance (GHC.Base.Semigroup a, GHC.Base.Monad f) => GHC.Base.Semigroup (Control.Exitcode.Exitcode.ExitcodeBifunctor f e a)
+ Control.Exitcode.Exitcode: instance Control.Monad.Cont.Class.MonadCont f => Control.Monad.Cont.Class.MonadCont (Control.Exitcode.Exitcode.Exitcode e f)
+ Control.Exitcode.Exitcode: instance Control.Monad.Cont.Class.MonadCont f => Control.Monad.Cont.Class.MonadCont (Control.Exitcode.Exitcode.ExitcodeBifunctor f e)
+ Control.Exitcode.Exitcode: instance Control.Monad.Error.Class.MonadError e f => Control.Monad.Error.Class.MonadError e (Control.Exitcode.Exitcode.Exitcode e' f)
+ Control.Exitcode.Exitcode: instance Control.Monad.Error.Class.MonadError e f => Control.Monad.Error.Class.MonadError e (Control.Exitcode.Exitcode.ExitcodeBifunctor f e')
+ Control.Exitcode.Exitcode: instance Control.Monad.Fix.MonadFix f => Control.Monad.Fix.MonadFix (Control.Exitcode.Exitcode.Exitcode e f)
+ Control.Exitcode.Exitcode: instance Control.Monad.Fix.MonadFix f => Control.Monad.Fix.MonadFix (Control.Exitcode.Exitcode.ExitcodeBifunctor f e)
+ Control.Exitcode.Exitcode: instance Control.Monad.IO.Class.MonadIO f => Control.Monad.IO.Class.MonadIO (Control.Exitcode.Exitcode.Exitcode e f)
+ Control.Exitcode.Exitcode: instance Control.Monad.IO.Class.MonadIO f => Control.Monad.IO.Class.MonadIO (Control.Exitcode.Exitcode.ExitcodeBifunctor f e)
+ Control.Exitcode.Exitcode: instance Control.Monad.RWS.Class.MonadRWS r w s f => Control.Monad.RWS.Class.MonadRWS r w s (Control.Exitcode.Exitcode.Exitcode e f)
+ Control.Exitcode.Exitcode: instance Control.Monad.RWS.Class.MonadRWS r w s f => Control.Monad.RWS.Class.MonadRWS r w s (Control.Exitcode.Exitcode.ExitcodeBifunctor f e)
+ Control.Exitcode.Exitcode: instance Control.Monad.Reader.Class.MonadReader r f => Control.Monad.Reader.Class.MonadReader r (Control.Exitcode.Exitcode.Exitcode e f)
+ Control.Exitcode.Exitcode: instance Control.Monad.Reader.Class.MonadReader r f => Control.Monad.Reader.Class.MonadReader r (Control.Exitcode.Exitcode.ExitcodeBifunctor f e)
+ Control.Exitcode.Exitcode: instance Control.Monad.State.Class.MonadState s f => Control.Monad.State.Class.MonadState s (Control.Exitcode.Exitcode.Exitcode e f)
+ Control.Exitcode.Exitcode: instance Control.Monad.State.Class.MonadState s f => Control.Monad.State.Class.MonadState s (Control.Exitcode.Exitcode.ExitcodeBifunctor f e)
+ Control.Exitcode.Exitcode: instance Control.Monad.Trans.Class.MonadTrans (Control.Exitcode.Exitcode.Exitcode e)
+ Control.Exitcode.Exitcode: instance Control.Monad.Writer.Class.MonadWriter w f => Control.Monad.Writer.Class.MonadWriter w (Control.Exitcode.Exitcode.Exitcode e f)
+ Control.Exitcode.Exitcode: instance Control.Monad.Writer.Class.MonadWriter w f => Control.Monad.Writer.Class.MonadWriter w (Control.Exitcode.Exitcode.ExitcodeBifunctor f e)
+ Control.Exitcode.Exitcode: instance Data.Foldable.Foldable f => Data.Bifoldable.Bifoldable (Control.Exitcode.Exitcode.ExitcodeBifunctor f)
+ Control.Exitcode.Exitcode: instance Data.Foldable.Foldable f => Data.Foldable.Foldable (Control.Exitcode.Exitcode.Exitcode e f)
+ Control.Exitcode.Exitcode: instance Data.Foldable.Foldable f => Data.Foldable.Foldable (Control.Exitcode.Exitcode.ExitcodeBifunctor f e)
+ Control.Exitcode.Exitcode: instance Data.Functor.Bind.Trans.BindTrans (Control.Exitcode.Exitcode.Exitcode e)
+ Control.Exitcode.Exitcode: instance Data.Functor.Extend.Extend f => Data.Functor.Extend.Extend (Control.Exitcode.Exitcode.Exitcode e f)
+ Control.Exitcode.Exitcode: instance Data.Functor.Extend.Extend f => Data.Functor.Extend.Extend (Control.Exitcode.Exitcode.ExitcodeBifunctor f e)
+ Control.Exitcode.Exitcode: instance Data.Traversable.Traversable f => Data.Bitraversable.Bitraversable (Control.Exitcode.Exitcode.ExitcodeBifunctor f)
+ Control.Exitcode.Exitcode: instance Data.Traversable.Traversable f => Data.Traversable.Traversable (Control.Exitcode.Exitcode.Exitcode e f)
+ Control.Exitcode.Exitcode: instance Data.Traversable.Traversable f => Data.Traversable.Traversable (Control.Exitcode.Exitcode.ExitcodeBifunctor f e)
+ Control.Exitcode.Exitcode: instance GHC.Base.Functor f => Data.Bifunctor.Bifunctor (Control.Exitcode.Exitcode.ExitcodeBifunctor f)
+ Control.Exitcode.Exitcode: instance GHC.Base.Functor f => GHC.Base.Functor (Control.Exitcode.Exitcode.Exitcode e f)
+ Control.Exitcode.Exitcode: instance GHC.Base.Functor f => GHC.Base.Functor (Control.Exitcode.Exitcode.ExitcodeBifunctor f e)
+ Control.Exitcode.Exitcode: instance GHC.Base.Monad f => Data.Functor.Alt.Alt (Control.Exitcode.Exitcode.Exitcode e f)
+ Control.Exitcode.Exitcode: instance GHC.Base.Monad f => Data.Functor.Alt.Alt (Control.Exitcode.Exitcode.ExitcodeBifunctor f e)
+ Control.Exitcode.Exitcode: instance GHC.Base.Monad f => Data.Functor.Bind.Class.Apply (Control.Exitcode.Exitcode.Exitcode e f)
+ Control.Exitcode.Exitcode: instance GHC.Base.Monad f => Data.Functor.Bind.Class.Apply (Control.Exitcode.Exitcode.ExitcodeBifunctor f e)
+ Control.Exitcode.Exitcode: instance GHC.Base.Monad f => Data.Functor.Bind.Class.Bind (Control.Exitcode.Exitcode.Exitcode e f)
+ Control.Exitcode.Exitcode: instance GHC.Base.Monad f => Data.Functor.Bind.Class.Bind (Control.Exitcode.Exitcode.ExitcodeBifunctor f e)
+ Control.Exitcode.Exitcode: instance GHC.Base.Monad f => GHC.Base.Applicative (Control.Exitcode.Exitcode.Exitcode e f)
+ Control.Exitcode.Exitcode: instance GHC.Base.Monad f => GHC.Base.Applicative (Control.Exitcode.Exitcode.ExitcodeBifunctor f e)
+ Control.Exitcode.Exitcode: instance GHC.Base.Monad f => GHC.Base.Monad (Control.Exitcode.Exitcode.Exitcode e f)
+ Control.Exitcode.Exitcode: instance GHC.Base.Monad f => GHC.Base.Monad (Control.Exitcode.Exitcode.ExitcodeBifunctor f e)
+ Control.Exitcode.Exitcode: instance GHC.Classes.Eq (f (Data.Either.Either (e, Natural.NotZero) a)) => GHC.Classes.Eq (Control.Exitcode.Exitcode.Exitcode e f a)
+ Control.Exitcode.Exitcode: instance GHC.Classes.Eq (f (Data.Either.Either (e, Natural.NotZero) a)) => GHC.Classes.Eq (Control.Exitcode.Exitcode.ExitcodeBifunctor f e a)
+ Control.Exitcode.Exitcode: instance GHC.Classes.Ord (f (Data.Either.Either (e, Natural.NotZero) a)) => GHC.Classes.Ord (Control.Exitcode.Exitcode.Exitcode e f a)
+ Control.Exitcode.Exitcode: instance GHC.Classes.Ord (f (Data.Either.Either (e, Natural.NotZero) a)) => GHC.Classes.Ord (Control.Exitcode.Exitcode.ExitcodeBifunctor f e a)
+ Control.Exitcode.Exitcode: instance GHC.Generics.Generic (Control.Exitcode.Exitcode.Exitcode e f a)
+ Control.Exitcode.Exitcode: instance GHC.Generics.Generic (Control.Exitcode.Exitcode.ExitcodeBifunctor f e a)
+ Control.Exitcode.Exitcode: instance GHC.Show.Show (f (Data.Either.Either (e, Natural.NotZero) a)) => GHC.Show.Show (Control.Exitcode.Exitcode.Exitcode e f a)
+ Control.Exitcode.Exitcode: instance GHC.Show.Show (f (Data.Either.Either (e, Natural.NotZero) a)) => GHC.Show.Show (Control.Exitcode.Exitcode.ExitcodeBifunctor f e a)
+ Control.Exitcode.Exitcode: instance WithIndex.FoldableWithIndex i f => WithIndex.FoldableWithIndex i (Control.Exitcode.Exitcode.Exitcode e f)
+ Control.Exitcode.Exitcode: instance WithIndex.FoldableWithIndex i f => WithIndex.FoldableWithIndex i (Control.Exitcode.Exitcode.ExitcodeBifunctor f e)
+ Control.Exitcode.Exitcode: instance WithIndex.FunctorWithIndex i f => WithIndex.FunctorWithIndex i (Control.Exitcode.Exitcode.Exitcode e f)
+ Control.Exitcode.Exitcode: instance WithIndex.FunctorWithIndex i f => WithIndex.FunctorWithIndex i (Control.Exitcode.Exitcode.ExitcodeBifunctor f e)
+ Control.Exitcode.Exitcode: instance WithIndex.TraversableWithIndex i f => WithIndex.TraversableWithIndex i (Control.Exitcode.Exitcode.Exitcode e f)
+ Control.Exitcode.Exitcode: instance WithIndex.TraversableWithIndex i f => WithIndex.TraversableWithIndex i (Control.Exitcode.Exitcode.ExitcodeBifunctor f e)
+ Control.Exitcode.Exitcode: liftTryExitcode :: Exception e' => IO a -> Exitcode e (ExceptT e' IO) a
+ Control.Exitcode.Exitcode: maybeExitcode :: Functor f => Exitcode e f a -> f (Maybe NotZero)
+ Control.Exitcode.Exitcode: maybeExitcode' :: Exitcode' e a -> Maybe NotZero
+ Control.Exitcode.Exitcode: mkExitFailure :: Applicative f => f NotZero -> f e -> Exitcode e f a
+ Control.Exitcode.Exitcode: mkExitFailure' :: NotZero -> e -> Exitcode' e a
+ Control.Exitcode.Exitcode: mkExitFailure1 :: Functor f => f e -> Exitcode e f a
+ Control.Exitcode.Exitcode: mkExitFailure1' :: e -> Exitcode' e a
+ Control.Exitcode.Exitcode: mkExitFailure_1 :: Functor f => f e -> Exitcode e f a
+ Control.Exitcode.Exitcode: mkExitFailure_1' :: e -> Exitcode' e a
+ Control.Exitcode.Exitcode: mkExitSuccess :: Functor f => f a -> Exitcode e f a
+ Control.Exitcode.Exitcode: mkExitSuccess' :: a -> Exitcode' e a
+ Control.Exitcode.Exitcode: mkExitcode :: Applicative f => f e -> f NotZero -> Exitcode e f a
+ Control.Exitcode.Exitcode: mkExitcode' :: e -> NotZero -> Exitcode' e a
+ Control.Exitcode.Exitcode: newtype Exitcode e (f :: Type -> Type) a
+ Control.Exitcode.Exitcode: newtype ExitcodeBifunctor (f :: Type -> Type) e a
+ Control.Exitcode.Exitcode: runExitcode :: Exitcode e f a -> f (Either (e, NotZero) a)
+ Control.Exitcode.Exitcode: toExitCode :: Functor f => Exitcode () f () -> f ExitCode
+ Control.Exitcode.Exitcode: toExitCode' :: Exitcode' () () -> ExitCode
+ Control.Exitcode.Exitcode: tryExitcode :: Exception e' => Exitcode e IO a -> Exitcode e (ExceptT e' IO) a
+ Control.Exitcode.Exitcode: type Exitcode' e a = Exitcode e Identity a
+ Control.Exitcode.Exitcode: type ExitcodeBifunctor' e a = ExitcodeBifunctor Identity e a
+ Control.Exitcode.Optics: _Exitcode :: AsExitcode t e f a => Prism' t (Exitcode e f a)
+ Control.Exitcode.Optics: _ExitcodeBifunctor :: AsExitcodeBifunctor t f e a => Prism' t (ExitcodeBifunctor f e a)
+ Control.Exitcode.Optics: class ReviewExitcode t e f a => AsExitcode t e (f :: Type -> Type) a | t -> e f a
+ Control.Exitcode.Optics: class ReviewExitcodeBifunctor t f e a => AsExitcodeBifunctor t (f :: Type -> Type) e a | t -> f e a
+ Control.Exitcode.Optics: class GetExitcode s e (f :: Type -> Type) a | s -> e f a
+ Control.Exitcode.Optics: class GetExitcodeBifunctor s (f :: Type -> Type) e a | s -> f e a
+ Control.Exitcode.Optics: class GetExitcode s e f a => HasExitcode s e (f :: Type -> Type) a | s -> e f a
+ Control.Exitcode.Optics: class GetExitcodeBifunctor s f e a => HasExitcodeBifunctor s (f :: Type -> Type) e a | s -> f e a
+ Control.Exitcode.Optics: class ReviewExitcode t e (f :: Type -> Type) a | t -> e f a
+ Control.Exitcode.Optics: class ReviewExitcodeBifunctor t (f :: Type -> Type) e a | t -> f e a
+ Control.Exitcode.Optics: exitcode :: HasExitcode s e f a => Lens' s (Exitcode e f a)
+ Control.Exitcode.Optics: exitcodeBifunctor :: HasExitcodeBifunctor s f e a => Lens' s (ExitcodeBifunctor f e a)
+ Control.Exitcode.Optics: getExitcode :: GetExitcode s e f a => Getter s (Exitcode e f a)
+ Control.Exitcode.Optics: getExitcodeBifunctor :: GetExitcodeBifunctor s f e a => Getter s (ExitcodeBifunctor f e a)
+ Control.Exitcode.Optics: instance Control.Exitcode.Optics.AsExitcode (Control.Exitcode.Exitcode.Exitcode e f a) e f a
+ Control.Exitcode.Optics: instance Control.Exitcode.Optics.AsExitcode (Control.Exitcode.Exitcode.ExitcodeBifunctor f e a) e f a
+ Control.Exitcode.Optics: instance Control.Exitcode.Optics.AsExitcodeBifunctor (Control.Exitcode.Exitcode.Exitcode e f a) f e a
+ Control.Exitcode.Optics: instance Control.Exitcode.Optics.AsExitcodeBifunctor (Control.Exitcode.Exitcode.ExitcodeBifunctor f e a) f e a
+ Control.Exitcode.Optics: instance Control.Exitcode.Optics.GetExitcode (Control.Exitcode.Exitcode.Exitcode e f a) e f a
+ Control.Exitcode.Optics: instance Control.Exitcode.Optics.GetExitcode (Control.Exitcode.Exitcode.ExitcodeBifunctor f e a) e f a
+ Control.Exitcode.Optics: instance Control.Exitcode.Optics.GetExitcodeBifunctor (Control.Exitcode.Exitcode.Exitcode e f a) f e a
+ Control.Exitcode.Optics: instance Control.Exitcode.Optics.GetExitcodeBifunctor (Control.Exitcode.Exitcode.ExitcodeBifunctor f e a) f e a
+ Control.Exitcode.Optics: instance Control.Exitcode.Optics.HasExitcode (Control.Exitcode.Exitcode.Exitcode e f a) e f a
+ Control.Exitcode.Optics: instance Control.Exitcode.Optics.HasExitcode (Control.Exitcode.Exitcode.ExitcodeBifunctor f e a) e f a
+ Control.Exitcode.Optics: instance Control.Exitcode.Optics.HasExitcodeBifunctor (Control.Exitcode.Exitcode.Exitcode e f a) f e a
+ Control.Exitcode.Optics: instance Control.Exitcode.Optics.HasExitcodeBifunctor (Control.Exitcode.Exitcode.ExitcodeBifunctor f e a) f e a
+ Control.Exitcode.Optics: instance Control.Exitcode.Optics.ReviewExitcode (Control.Exitcode.Exitcode.Exitcode e f a) e f a
+ Control.Exitcode.Optics: instance Control.Exitcode.Optics.ReviewExitcode (Control.Exitcode.Exitcode.ExitcodeBifunctor f e a) e f a
+ Control.Exitcode.Optics: instance Control.Exitcode.Optics.ReviewExitcodeBifunctor (Control.Exitcode.Exitcode.Exitcode e f a) f e a
+ Control.Exitcode.Optics: instance Control.Exitcode.Optics.ReviewExitcodeBifunctor (Control.Exitcode.Exitcode.ExitcodeBifunctor f e a) f e a
+ Control.Exitcode.Optics: reviewExitcode :: ReviewExitcode t e f a => Review t (Exitcode e f a)
+ Control.Exitcode.Optics: reviewExitcodeBifunctor :: ReviewExitcodeBifunctor t f e a => Review t (ExitcodeBifunctor f e a)
+ Control.Process.CmdSpec: RawCommand :: FilePath -> [String] -> CmdSpec
+ Control.Process.CmdSpec: ShellCommand :: String -> CmdSpec
+ Control.Process.CmdSpec: class GetCmdSpec a
+ Control.Process.CmdSpec: class ReviewCmdSpec a
+ Control.Process.CmdSpec: data CmdSpec
+ Control.Process.CmdSpec: getCmdSpec :: GetCmdSpec a => Getter a CmdSpec
+ Control.Process.CmdSpec: instance Control.Process.CmdSpec.GetCmdSpec System.Process.Common.CmdSpec
+ Control.Process.CmdSpec: instance Control.Process.CmdSpec.GetCmdSpec System.Process.Common.CreateProcess
+ Control.Process.CmdSpec: instance Control.Process.CmdSpec.ReviewCmdSpec System.Process.Common.CmdSpec
+ Control.Process.CmdSpec: reviewCmdSpec :: ReviewCmdSpec a => Review a CmdSpec
+ Control.Process.CreateProcess: class GetCreateProcess a
+ Control.Process.CreateProcess: class ReviewCreateProcess a
+ Control.Process.CreateProcess: data CreateProcess
+ Control.Process.CreateProcess: getCreateProcess :: GetCreateProcess a => Getter a CreateProcess
+ Control.Process.CreateProcess: instance Control.Process.CreateProcess.GetCreateProcess System.Process.Common.CreateProcess
+ Control.Process.CreateProcess: instance Control.Process.CreateProcess.ReviewCreateProcess System.Process.Common.CreateProcess
+ Control.Process.CreateProcess: reviewCreateProcess :: ReviewCreateProcess a => Review a CreateProcess
+ Control.Process.FD: class GetFD a
+ Control.Process.FD: class ReviewFD a
+ Control.Process.FD: getFD :: GetFD a => Getter a FD
+ Control.Process.FD: getFDInt32 :: GetFD a => Getter a Int32
+ Control.Process.FD: instance Control.Process.FD.GetFD System.Posix.Internals.FD
+ Control.Process.FD: instance Control.Process.FD.ReviewFD System.Posix.Internals.FD
+ Control.Process.FD: reviewFD :: ReviewFD a => Review a FD
+ Control.Process.FD: reviewFDInt32 :: ReviewFD a => Review a Int32
+ Control.Process.FD: type FD = CInt
+ Control.Process.GroupID: class GetGroupID a
+ Control.Process.GroupID: class ReviewGroupID a
+ Control.Process.GroupID: getGroupID :: GetGroupID a => Getter a GroupID
+ Control.Process.GroupID: instance Control.Process.GroupID.GetGroupID System.Posix.Types.GroupID
+ Control.Process.GroupID: instance Control.Process.GroupID.ReviewGroupID System.Posix.Types.GroupID
+ Control.Process.GroupID: reviewGroupID :: ReviewGroupID a => Review a GroupID
+ Control.Process.GroupID: type GroupID = CGid
+ Control.Process.Handle: class GetHandle a
+ Control.Process.Handle: class ReviewHandle a
+ Control.Process.Handle: data Handle
+ Control.Process.Handle: getHandle :: GetHandle a => Getter a Handle
+ Control.Process.Handle: instance Control.Process.Handle.GetHandle GHC.IO.Handle.Types.Handle
+ Control.Process.Handle: instance Control.Process.Handle.ReviewHandle GHC.IO.Handle.Types.Handle
+ Control.Process.Handle: instance Control.Process.Handle.ReviewHandle System.Process.Common.StdStream
+ Control.Process.Handle: reviewHandle :: ReviewHandle a => Review a Handle
+ Control.Process.Pid: class GetPid a
+ Control.Process.Pid: class ReviewPid a
+ Control.Process.Pid: instance Control.Process.Pid.GetPid System.Process.Pid
+ Control.Process.Pid: instance Control.Process.Pid.ReviewPid System.Process.Pid
+ Control.Process.Pid: reviewPid :: ReviewPid a => Review a Pid
+ Control.Process.Pid: reviewPidInt32 :: ReviewPid a => Review a Int32
+ Control.Process.Pid: type Pid = CPid
+ Control.Process.Pid: viewPid :: GetPid a => Getter a Pid
+ Control.Process.Pid: viewPidInt32 :: GetPid a => Getter a Int32
+ Control.Process.ProcessHandle: class GetProcessHandle a
+ Control.Process.ProcessHandle: class ReviewProcessHandle a
+ Control.Process.ProcessHandle: data ProcessHandle
+ Control.Process.ProcessHandle: getProcessHandle :: GetProcessHandle a => Getter a ProcessHandle
+ Control.Process.ProcessHandle: instance Control.Process.ProcessHandle.GetProcessHandle System.Process.Common.ProcessHandle
+ Control.Process.ProcessHandle: instance Control.Process.ProcessHandle.ReviewProcessHandle System.Process.Common.ProcessHandle
+ Control.Process.ProcessHandle: reviewProcessHandle :: ReviewProcessHandle a => Review a ProcessHandle
+ Control.Process.StdStream: _UseHandle :: AsStdStream a => Prism' a Handle
+ Control.Process.StdStream: class GetStdStream a
+ Control.Process.StdStream: class ReviewStdStream a
+ Control.Process.StdStream: getStdStream :: GetStdStream a => Getter a StdStream
+ Control.Process.StdStream: instance Control.Process.StdStream.GetStdStream System.Process.Common.StdStream
+ Control.Process.StdStream: instance Control.Process.StdStream.ReviewStdStream System.Process.Common.StdStream
+ Control.Process.StdStream: reviewStdStream :: ReviewStdStream a => Review a StdStream
+ Control.Process.UserID: class GetUserID a
+ Control.Process.UserID: class ReviewUserID a
+ Control.Process.UserID: getUserID :: GetUserID a => Getter a UserID
+ Control.Process.UserID: getUserIDWord32 :: GetUserID a => Getter a Word32
+ Control.Process.UserID: instance Control.Process.UserID.GetUserID System.Posix.Types.UserID
+ Control.Process.UserID: instance Control.Process.UserID.ReviewUserID System.Posix.Types.UserID
+ Control.Process.UserID: reviewUserID :: ReviewUserID a => Review a UserID
+ Control.Process.UserID: reviewUserIDWord32 :: ReviewUserID a => Review a Word32
+ Control.Process.UserID: type UserID = CUid
- Control.Process.CmdSpec: class AsCmdSpec a
+ Control.Process.CmdSpec: class ReviewCmdSpec a => AsCmdSpec a
- Control.Process.CmdSpec: class HasCmdSpec a
+ Control.Process.CmdSpec: class GetCmdSpec a => HasCmdSpec a
- Control.Process.CreateProcess: class AsCreateProcess a
+ Control.Process.CreateProcess: class ReviewCreateProcess a => AsCreateProcess a
- Control.Process.CreateProcess: class HasCreateProcess a
+ Control.Process.CreateProcess: class GetCreateProcess a => HasCreateProcess a
- Control.Process.FD: class AsFD a
+ Control.Process.FD: class ReviewFD a => AsFD a
- Control.Process.FD: class HasFD a
+ Control.Process.FD: class GetFD a => HasFD a
- Control.Process.GroupID: class AsGroupID a
+ Control.Process.GroupID: class ReviewGroupID a => AsGroupID a
- Control.Process.GroupID: class HasGroupID a
+ Control.Process.GroupID: class GetGroupID a => HasGroupID a
- Control.Process.Handle: class AsHandle a
+ Control.Process.Handle: class ReviewHandle a => AsHandle a
- Control.Process.Handle: class HasHandle a
+ Control.Process.Handle: class GetHandle a => HasHandle a
- Control.Process.Pid: class AsPid a
+ Control.Process.Pid: class ReviewPid a => AsPid a
- Control.Process.Pid: class HasPid a
+ Control.Process.Pid: class GetPid a => HasPid a
- Control.Process.Process: getProcessExitCode :: Exception e' => ProcessHandle -> ExitcodeT (ExceptT e' IO) (Maybe ()) (Maybe ())
+ Control.Process.Process: getProcessExitCode :: Exception e' => ProcessHandle -> Exitcode (Maybe ()) (ExceptT e' IO) (Maybe ())
- Control.Process.Process: getProcessExitCodeBool :: Exception e' => ProcessHandle -> ExitcodeT (ExceptT e' IO) Bool Bool
+ Control.Process.Process: getProcessExitCodeBool :: Exception e' => ProcessHandle -> Exitcode Bool (ExceptT e' IO) Bool
- Control.Process.Process: readCreateProcessWithExitCode :: Exception e' => CreateProcess -> String -> ExitcodeT (ExceptT e' IO) (String, String) (String, String)
+ Control.Process.Process: readCreateProcessWithExitCode :: Exception e' => CreateProcess -> String -> Exitcode (String, String) (ExceptT e' IO) (String, String)
- Control.Process.Process: readProcessWithExitCode :: Exception e' => FilePath -> [String] -> String -> ExitcodeT (ExceptT e' IO) (String, String) (String, String)
+ Control.Process.Process: readProcessWithExitCode :: Exception e' => FilePath -> [String] -> String -> Exitcode (String, String) (ExceptT e' IO) (String, String)
- Control.Process.Process: waitForProcess :: Exception e' => ProcessHandle -> ExitcodeT (ExceptT e' IO) () ()
+ Control.Process.Process: waitForProcess :: Exception e' => ProcessHandle -> Exitcode () (ExceptT e' IO) ()
- Control.Process.ProcessHandle: class AsProcessHandle a
+ Control.Process.ProcessHandle: class ReviewProcessHandle a => AsProcessHandle a
- Control.Process.ProcessHandle: class HasProcessHandle a
+ Control.Process.ProcessHandle: class GetProcessHandle a => HasProcessHandle a
- Control.Process.StdStream: class AsStdStream a
+ Control.Process.StdStream: class ReviewStdStream a => AsStdStream a
- Control.Process.StdStream: class HasStdStream a
+ Control.Process.StdStream: class GetStdStream a => HasStdStream a
- Control.Process.UserID: class AsUserID a
+ Control.Process.UserID: class ReviewUserID a => AsUserID a
- Control.Process.UserID: class HasUserID a
+ Control.Process.UserID: class GetUserID a => HasUserID a

Files

+ README.md view
@@ -0,0 +1,5 @@+# exitcode++Monad transformer for exit codes++![System-F](https://logo.systemf.com.au/systemf-450x450.jpg)
Setup.hs view
@@ -1,2 +1,8 @@-import Distribution.Simple+{-# OPTIONS_GHC -Wall -Werror #-}++module Main (main) where++import Distribution.Simple (defaultMain)++main :: IO () main = defaultMain
+ benchmarks/Main.hs view
@@ -0,0 +1,36 @@+{-# OPTIONS_GHC -Wall -Werror #-}++module Main (main) where++import Control.Exitcode (Exitcode', mkExitFailure1', mkExitSuccess', runExitcode)+import Data.Functor.Identity (runIdentity)+import Test.Tasty.Bench (bench, bgroup, defaultMain, whnf)++n :: Int+n = 1000++bindChain :: Int -> Exitcode' () Int+bindChain depth = iterate (\acc -> acc >>= \x -> mkExitSuccess' (x + 1)) (mkExitSuccess' 0) !! depth+{-# NOINLINE bindChain #-}++failShortCircuit :: Int -> Exitcode' () Int+failShortCircuit depth = iterate (\acc -> acc >>= \x -> mkExitSuccess' (x + 1)) (mkExitFailure1' () >> mkExitSuccess' 0) !! depth+{-# NOINLINE failShortCircuit #-}++failPropagation :: Int -> Exitcode' Int Int+failPropagation depth = iterate (\acc -> acc >>= \_ -> mkExitFailure1' 0) (mkExitSuccess' 0) !! depth+{-# NOINLINE failPropagation #-}++main :: IO ()+main =+  defaultMain+    [ bgroup+        "Exitcode"+        [ bgroup+            "bind"+            [ bench "success-chain" $ whnf (runIdentity . runExitcode . bindChain) n,+              bench "fail-short-circuit" $ whnf (runIdentity . runExitcode . failShortCircuit) n,+              bench "fail-propagation" $ whnf (runIdentity . runExitcode . failPropagation) n+            ]+        ]+    ]
changelog.md view
@@ -1,3 +1,22 @@+0.3.0.0++* Replace `Int` exit code representation with `NotZero` from the `natural` package, making it impossible to construct a failure with exit code 0+* Introduce `ExitcodeBifunctor` newtype enabling `Bifunctor`, `Bifoldable`, and `Bitraversable` instances+* Add `bimapExitcode` for mapping both error and success values+* Add `toExitCode` and `toExitCode'` as inverses of `fromExitCode`/`fromExitCode'`+* Add `maybeExitcode` and `maybeExitcode'` for extracting exit code as `Maybe NotZero`+* Add `embedExitcode` for embedding natural transformations+* Add `_ExitFailureCode`, `_ExitFailureCode'`, `_ExitFailureValue`, `_ExitFailureValue'` optics+* Add four-level classy optics hierarchy (`Get`/`Has`/`Review`/`As`) for all `Control.Process` types+* Add `_UseHandle` prism to `AsStdStream`+* Add `streams` and `streams1` traversals for `CreateProcess`+* Remove `mapExitcode` (subsumed by `ExitcodeBifunctor`)+* Rename `ExitcodeT` to `Exitcode`, `ExitcodeT1` to removed+* Add `NFData` and `NFData1` instances+* Add fusion RULES for `exitcodeMap` and `exitcodeFoldMap`+* Add comprehensive doctest coverage (291 tests)+* Add benchmarks+ 0.2.0.0  * some API updates
exitcode.cabal view
@@ -1,31 +1,38 @@--- documentation, see http://haskell.org/cabal/users-guide/-+cabal-version:          2.4 name:                   exitcode-version:                0.2.0.0+version:                0.3.0.0 synopsis:               Monad transformer for exit codes description:   Monad transformer for exit codes   .   <<https://logo.systemf.com.au/systemf-450x450.jpg>>-license:                BSD3+license:                BSD-3-Clause license-file:           LICENCE author:                 Queensland Functional Programming Lab <oᴉ˙ldɟb@llǝʞsɐɥ> maintainer:             Tony Morris <oᴉ˙ldɟb@llǝʞsɐɥ> copyright:              Copyright (C) 2019-2025 Tony Morris category:               Control build-type:             Simple-extra-source-files:     changelog.md-cabal-version:          >=1.10+extra-doc-files:        changelog.md+                      , README.md homepage:               https://gitlab.com/system-f/code/exitcode bug-reports:            https://gitlab.com/system-f/code/exitcode/issues-tested-with:             GHC == 7.10.3, GHC == 8.0.2, GHC == 8.2.2, GHC == 8.4.3, GHC == 8.6.1, GHC == 9.4.8, GHC == 9.6.7+tested-with:            GHC == 9.6.7 +flag dev+  description:          Enable development warnings (-Werror, -O2 for benchmarks)+  manual:               True+  default:              False+ source-repository       head   type:                 git   location:             git@gitlab.com:system-f/code/exitcode.git  library   exposed-modules:      Control.Exitcode+                        Control.Exitcode.Exitcode+                        Control.Exitcode.Optics+                        Control.Process.Process                         Control.Process                         Control.Process.CmdSpec                         Control.Process.CreateProcess@@ -33,41 +40,48 @@                         Control.Process.GroupID                         Control.Process.Handle                         Control.Process.Pid-                        Control.Process.Process                         Control.Process.ProcessHandle                         Control.Process.StdStream                         Control.Process.UserID    build-depends:        base >= 4.8 && < 6                       , bifunctors >= 5 && < 6+                      , comonad >= 5 && < 6+                      , deepseq >= 1.4 && < 2                       , filepath >= 1.4 && < 2                       , lens >= 4.15 && < 6                       , mtl >= 2.2 && < 3                       , process >= 1.6.12.0 && < 2                       , semigroupoids >= 5.1 && < 7-                      , semigroups >= 0.16 && < 1-                      , transformers >= 0.5.0 && < 1+                      , transformers >= 0.5 && < 1+                      , natural >= 0.5.0.1 && < 1+   hs-source-dirs:       src   default-language:     Haskell2010   ghc-options:          -Wall -test-suite             tests-  build-depends:       QuickCheck >= 2.9.2 && < 2.13-                     , base >= 4.8 && < 6-                     , bifunctors >= 5 && < 6-                     , checkers >= 0.4.6 && < 0.5-                     , exitcode-                     , hedgehog >= 0.5 && < 0.7-                     , lens >= 4.15 && < 6-                     , mtl >= 2.2 && < 2.3-                     , semigroupoids >= 5.1 && < 5.4-                     , tasty >= 0.11 && < 1.3-                     , tasty-hunit >= 0.9 && < 0.11-                     , tasty-hedgehog >= 0.1 && < 0.3-                     , tasty-quickcheck >= 0.8.4 && < 0.11-                     , transformers >= 0.5.0 && < 5.5-  type:                exitcode-stdio-1.0-  main-is:             Tests.hs-  hs-source-dirs:      test-  default-language:    Haskell2010-  ghc-options:         -Wall+  if flag(dev)+    ghc-options:        -Werror++test-suite doctest+  type:                 exitcode-stdio-1.0+  hs-source-dirs:       test+  main-is:              Main.hs+  build-depends:        base >= 4.8 && < 6+                      , process >= 1 && < 2+  build-tool-depends:   doctest:doctest >= 0.22 && < 1+  default-language:     Haskell2010+  ghc-options:          -Wall++benchmark bench+  type:                 exitcode-stdio-1.0+  hs-source-dirs:       benchmarks+  main-is:              Main.hs+  build-depends:        base >= 4.8 && < 6+                      , tasty-bench >= 0.3 && < 1+                      , exitcode+  default-language:     Haskell2010+  ghc-options:          -Wall++  if flag(dev)+    ghc-options:        -Werror -O2
src/Control/Exitcode.hs view
@@ -1,816 +1,11 @@-{-# OPTIONS_GHC -Wall #-} {-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TupleSections #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE LambdaCase #-}-{-# LANGUAGE RankNTypes #-}--module Control.Exitcode (--- * Types-  ExitcodeT-, Exitcode-, ExitcodeT0-, Exitcode0-, ExitcodeT1-, Exitcode1--- * Construction-, exitsuccess-, exitsuccess0-, exitfailure-, exitfailure0-, exitfailureNeg1-, exitcodeValue-, exitcodeValue0-, fromExitCode-, fromExitCode'-, liftExitcode-, liftExitcodeFailure-, liftExitcodeFailure0-, liftExitFailureNeg1-, hoistExitcode-, embedExitcode-, exitcode1--- * Extraction-, runExitcodeT-, maybeExitcodeT-, runExitcode-, maybeExitcode-, runExitcodeT1-, runExitcode1--- * Exceptions-, tryExitcode-, liftTryExitcode--- * Optics-, exitCode-, _ExitcodeInt-, _ExitcodeInt'-, _ExitFailure-, _ExitFailureError-, _ExitSuccess-, _Exitcode1-) where---import Control.Applicative-    ( Applicative((<*>), pure, liftA2) )-import Control.Category ( Category((.)) )-import Control.Exception ( try, Exception )-import Control.Lens-    ( preview,-      view,-      iso,-      _Left,-      prism,-      over,-      Field1(_1),-      Field2(_2),-      Iso,-      Lens,-      Prism,-      Traversal,-      Traversal' )-import Control.Monad ( join, Monad(return, (>>=)) )-import Control.Monad.Cont.Class ( MonadCont(..) )-import Control.Monad.Error.Class ( MonadError(..) )-import Control.Monad.Except ( ExceptT(..) )-import Control.Monad.IO.Class ( MonadIO(..) )-import Control.Monad.Reader ( MonadReader(ask, local) )-import Control.Monad.RWS.Class ( MonadRWS )-import Control.Monad.State.Lazy ( MonadState(get, put) )-import Control.Monad.Trans.Maybe ( MaybeT(MaybeT) )-import Control.Monad.Writer.Class ( MonadWriter(..) )-import Data.Bifoldable ( Bifoldable(bifoldMap) )-import Data.Bifunctor ( Bifunctor(bimap) )-import Data.Bitraversable ( Bitraversable(..) )-import Data.Bool ( bool )-import Data.Either ( Either(..), either )-import Data.Eq ( Eq((==)) )-import Data.Foldable ( Foldable(foldMap) )-import Data.Function ( ($), const )-import Data.Functor ( Functor(fmap), (<$>) )-import Data.Functor.Alt ( Alt((<!>)) )-import Data.Functor.Apply ( Apply((<.>)) )-import Data.Functor.Bind ( Bind((>>-)) )-import Data.Functor.Classes-    ( compare1,-      eq1,-      showsPrec1,-      showsUnaryWith,-      Eq1(..),-      Ord1(..),-      Show1(..) )-import Data.Functor.Extend ( Extend(..) )-import Data.Functor.Identity ( Identity(Identity, runIdentity) )-import Data.Int ( Int )-import Data.Maybe ( Maybe(Nothing, Just), fromMaybe )-import Data.Monoid ( Monoid(mempty) )-import Data.Ord ( Ord(compare) )-import Data.Semigroup ( Semigroup((<>)) )-import Data.Traversable ( Traversable(traverse) )-import Data.Tuple ( uncurry )-import GHC.Show ( Show(showsPrec) )-import System.Exit ( ExitCode(..) )-import System.IO ( IO )---- $setup--- >>> import Prelude--- >>> import Control.Lens---- | An exit code status where failing with a value `0` cannot be represented.------ Transformer for either a (non-zero exit code value (`Int`) with error :: `e`) or a (value :: `a`).-newtype ExitcodeT f e a =-  ExitcodeT (f (Either (e, Int) a))--type Exitcode e a =-  ExitcodeT Identity e a--type ExitcodeT0 f =-  ExitcodeT f () ()--type Exitcode0 =-  Exitcode () ()---- | Construct a succeeding exit code with the given value.------ >>> exitsuccess "abc" :: ExitcodeT Identity () String--- ExitcodeT (Identity (Right "abc"))-exitsuccess ::-  Applicative f =>-  a-  -> ExitcodeT f e a-exitsuccess =-  ExitcodeT . pure . Right---- | Construct a succeeding exit code with unit.------ >>> exitsuccess0 :: ExitcodeT0 Identity--- ExitcodeT (Identity (Right ()))-exitsuccess0 ::-  Applicative f =>-  ExitcodeT f e ()-exitsuccess0 =-  exitsuccess ()---- | Construct a failing exit code with the given status.------ If the given status is `0` then the exit code will succeed with unit.------ >>> exitfailure 'x' 99 :: ExitcodeT Identity Char ()--- ExitcodeT (Identity (Left ('x',99)))-exitfailure ::-  Applicative f =>-  e-  -> Int-  -> ExitcodeT f e ()-exitfailure e n =-  exitcodeValue e n ()---- | Construct a failing exit code with the given status.------ If the given status is `0` then the exit code will succeed with unit.-exitfailure0 ::-  Applicative f =>-  Int-  -> ExitcodeT0 f-exitfailure0 =-  exitfailure ()---- | Construct a failing exit code with the given status.--- If zero (0) is passed meaning success, use negative one (-1).------ >>> exitfailureNeg1 "abc" 0 :: Exitcode String ()--- ExitcodeT (Identity (Left ("abc",-1)))------ >>> exitfailureNeg1 "abc" 12 :: Exitcode String ()--- ExitcodeT (Identity (Left ("abc",12)))-exitfailureNeg1 ::-  Applicative f =>-  e-  -> Int-  -> ExitcodeT f e a-exitfailureNeg1 e n =-  liftExitFailureNeg1 (pure (e, n))---- | Construct an exit code with the given status.--- Associate a value of type `e` with a failing exit code and a value of the type `a` with a success exit code.------ If the given status is `0` then the exit code will succeed with unit.------ >>> exitcodeValue 'x' 99 "abc" :: ExitcodeT Identity Char String--- ExitcodeT (Identity (Left ('x',99)))--- >>> exitcodeValue 'x' 0 "abc" :: ExitcodeT Identity Char String--- ExitcodeT (Identity (Right "abc"))-exitcodeValue ::-  Applicative f =>-  e-  -> Int-  -> a-  -> ExitcodeT f e a-exitcodeValue e n =-  liftExitcodeFailure (pure (e, n))---- | Construct an exit code with the given status.------ If the given status is `0` then the exit code will succeed with unit.------ >>> exitcodeValue0 99 :: ExitcodeT0 Identity--- ExitcodeT (Identity (Left ((),99)))--- >>> exitcodeValue0 0 :: ExitcodeT0 Identity--- ExitcodeT (Identity (Right ()))-exitcodeValue0 ::-  Applicative f =>-  Int-  -> ExitcodeT0 f-exitcodeValue0 n =-  exitcodeValue () n ()---- | From base exitcode.------ >>> fromExitCode (Identity ExitSuccess)--- ExitcodeT (Identity (Right ()))--- >>> fromExitCode (Identity (ExitFailure 99))--- ExitcodeT (Identity (Left ((),99)))-fromExitCode ::-  Functor f =>-  f ExitCode-  -> ExitcodeT0 f-fromExitCode x =-  let ExitcodeT (MaybeT r) = view exitCode x-  in  ExitcodeT (fromMaybe (Right ()) <$> r)---- | From base exitcode.------ >>> fromExitCode' ExitSuccess--- ExitcodeT (Identity (Right ()))--- >>> fromExitCode' (ExitFailure 99)--- ExitcodeT (Identity (Left ((),99)))--- >>> fromExitCode' (ExitFailure 0)--- ExitcodeT (Identity (Right ()))-fromExitCode' ::-  ExitCode-  -> Exitcode0-fromExitCode' =-  fromExitCode . Identity---- | Isomorphism from base exitcode to underlying `Maybe (Either Int ())` where `Int` is non-zero.------ >>> view exitCode (Identity (ExitFailure 99))--- ExitcodeT (MaybeT (Identity (Just (Left ((),99)))))--- >>> view exitCode (Identity ExitSuccess)--- ExitcodeT (MaybeT (Identity (Just (Right ()))))--- >>> review exitCode (exitfailure0 99) :: Identity ExitCode--- Identity (ExitFailure 99)--- >>> review exitCode exitsuccess0 :: Identity ExitCode--- Identity ExitSuccess-exitCode ::-  (Functor f, Functor g) =>-  Iso-    (f ExitCode)-    (g ExitCode)-    (ExitcodeT0 (MaybeT f))-    (ExitcodeT0 (MaybeT g))-exitCode =-  iso-    (\x -> ExitcodeT (MaybeT ((\case-                                ExitSuccess ->-                                  Just (Right ())-                                ExitFailure 0 ->-                                  Nothing-                                ExitFailure n ->-                                  Just (Left ((), n))) <$> x)))-    (\(ExitcodeT (MaybeT x)) -> (\case-                                  Just (Right ()) ->-                                    ExitSuccess-                                  Nothing ->-                                    ExitFailure 0-                                  Just (Left ((), n)) ->-                                    ExitFailure n) <$> x)---- | Extract either the non-zero value or the success value.------ >>> runExitcodeT exitsuccess0 :: Identity (Either ((), Int) ())--- Identity (Right ())--- >>> runExitcodeT (exitfailure0 99) :: Identity (Either ((), Int) ())--- Identity (Left ((),99))-runExitcodeT ::-  ExitcodeT f e a-  -> f (Either (e, Int) a)-runExitcodeT (ExitcodeT x) =-  x---- | Extract either the non-zero value or `Nothing`.------ >>> maybeExitcodeT exitsuccess0 :: Identity (Maybe Int)--- Identity Nothing--- >>> maybeExitcodeT (exitfailure0 99) :: Identity (Maybe Int)--- Identity (Just 99)-maybeExitcodeT ::-  Functor f =>-  ExitcodeT f e a-  -> f (Maybe Int)-maybeExitcodeT x =-  preview (_Left . _2) <$> runExitcodeT x---- | Extract either the non-zero value or the success value.------ >>> runExitcode exitsuccess0 :: Either ((), Int) ()--- Right ()--- >>> runExitcode (exitfailure0 99) :: Either ((), Int) ()--- Left ((),99)-runExitcode ::-  Exitcode e a-  -> Either (e, Int) a-runExitcode =-  runIdentity . runExitcodeT---- | Extract either the non-zero value or `Nothing`.------ >>> maybeExitcode exitsuccess0 :: Maybe Int--- Nothing--- >>> maybeExitcode (exitfailure0 99) :: Maybe Int--- Just 99-maybeExitcode ::-  Exitcode0-  -> Maybe Int-maybeExitcode =-  runIdentity . maybeExitcodeT---- | Isomorphism to integer.------ >>> view _ExitcodeInt exitsuccess0 :: [Int]--- [0]--- >>> view _ExitcodeInt (exitfailure0 99) :: [Int]--- [99]--- >>> review _ExitcodeInt [0]--- ExitcodeT [Right ()]--- >>> review _ExitcodeInt [99]--- ExitcodeT [Left ((),99)]-_ExitcodeInt ::-  (Functor f, Functor f') =>-  Iso-    (ExitcodeT0 f)-    (ExitcodeT0 f')-    (f Int)-    (f' Int)-_ExitcodeInt =-  iso-    (\(ExitcodeT x) -> fmap (either (view _2) (\() -> 0)) x)-    (\x -> liftExitcodeFailure (((),) <$> x) ())---- | Setter to integer.------ >>> preview _ExitcodeInt' (exitsuccess0 :: ExitcodeT0 [])--- Just 0--- >>> preview _ExitcodeInt' (exitfailure0 99 :: ExitcodeT0 [])--- Just 99--- >>> preview _ExitcodeInt' (exitfailure0 0 :: ExitcodeT0 [])--- Just 0--- >>> over _ExitcodeInt' (subtract 1) exitsuccess0 :: ExitcodeT0 Identity--- ExitcodeT (Identity (Left ((),-1)))--- >>> over _ExitcodeInt' (subtract 1) (exitfailure0 99) :: ExitcodeT0 Identity--- ExitcodeT (Identity (Left ((),98)))--- >>> over _ExitcodeInt' (subtract 1) (exitfailure0 1) :: ExitcodeT0 Identity--- ExitcodeT (Identity (Right ()))-_ExitcodeInt' ::-  Traversable f =>-  Traversal'-    (ExitcodeT0 f)-    Int-_ExitcodeInt' =-  _ExitcodeInt . traverse---- | A traversal to exit failure.------ >>> preview _ExitFailure (exitfailure0 99 :: ExitcodeT0 Identity)--- Just ((),99)--- >>> preview _ExitFailure (exitsuccess0 :: ExitcodeT0 Identity)--- Nothing--- >>> over _ExitFailure (\(e, n) -> (e + 1, n + 1)) (exitsuccess0 :: ExitcodeT Identity Int ())--- ExitcodeT (Identity (Right ()))--- >>> over _ExitFailure (\(e, n) -> (reverse e, n + 1)) (exitfailure "abc" 1 :: ExitcodeT Identity String ())--- ExitcodeT (Identity (Left ("cba",2)))--- >>> over _ExitFailure (\(e, n) -> (reverse e, n - 1)) (exitfailure "abc" 1 :: ExitcodeT Identity String ())--- ExitcodeT (Identity (Right ()))-_ExitFailure ::-  Traversable f =>-  Traversal-    (ExitcodeT f e ())-    (ExitcodeT f e' ())-    (e, Int)-    (e', Int)-_ExitFailure f (ExitcodeT x) =-  ExitcodeT <$> traverse (either (\z -> runExitcodeT (liftExitcodeFailure (f z) ())) (pure . pure)) x---- | A traversal over the associated failing value.------ >>> over _ExitFailureError reverse exitsuccess0 :: ExitcodeT Identity [Int] ()--- ExitcodeT (Identity (Right ()))--- >>> over _ExitFailureError reverse (exitfailure "abc" 99) :: ExitcodeT Identity String ()--- ExitcodeT (Identity (Left ("cba",99)))--- >>> over _ExitFailureError reverse (exitfailure "abc" 0) :: ExitcodeT Identity String ()--- ExitcodeT (Identity (Right ()))--- >>> preview _ExitFailureError (exitfailure0 99 :: ExitcodeT0 Identity)--- Just ()--- >>> preview _ExitFailureError (exitsuccess0 :: ExitcodeT0 Identity)--- Nothing-_ExitFailureError ::-  Traversable f =>-  Traversal-    (ExitcodeT f e a)-    (ExitcodeT f e' a)-    e-    e'-_ExitFailureError f (ExitcodeT x) =-  ExitcodeT <$> traverse (either (\(e, n) -> (\e' -> Left (e', n)) <$> f e) (pure . Right)) x---- | A prism to exit success.------ >>> over _ExitSuccess (\x -> x) (exitfailure0 99)--- ExitcodeT (Identity (Left ((),99)))--- >>> over _ExitSuccess (\x -> x) (exitfailure0 0)--- ExitcodeT (Identity (Right ()))--- >>> over _ExitSuccess (\x -> x) (exitfailure0 0)--- ExitcodeT (Identity (Right ()))--- >>> preview _ExitSuccess (exitfailure0 99)--- Nothing--- >>> preview _ExitSuccess exitsuccess0--- Just ()--- >>> review _ExitSuccess "abc" :: ExitcodeT Identity () String--- ExitcodeT (Identity (Right "abc"))-_ExitSuccess ::-  Prism-    (Exitcode e a)-    (Exitcode e a')-    a-    a'-_ExitSuccess =-  prism-    exitsuccess-    (\(ExitcodeT (Identity x)) ->-      over _Left (ExitcodeT . Identity . Left) x-    )--instance Functor f => Functor (ExitcodeT f e) where-  fmap f (ExitcodeT x) =-    ExitcodeT (fmap (fmap f) x)--instance Monad f => Apply (ExitcodeT f e) where-  ExitcodeT f <.> ExitcodeT a =-    ExitcodeT (f >>= either (pure . Left) (\f' -> fmap (fmap f') a))--instance Monad f => Applicative (ExitcodeT f e) where-  pure =-    ExitcodeT . pure . pure-  ExitcodeT f <*> ExitcodeT a =-    ExitcodeT (f >>= either (pure . Left) (\f' -> fmap (fmap f') a))---- |------ >>> exitsuccess "abc" >>- \s -> exitsuccess (reverse s) :: ExitcodeT Identity () String--- ExitcodeT (Identity (Right "cba"))--- >>> exitsuccess "abc" >>- \_ -> exitfailure0 99 :: ExitcodeT0 Identity--- ExitcodeT (Identity (Left ((),99)))--- >>> exitfailure 'x' 99 >>- \_ -> exitsuccess "abc" :: ExitcodeT Identity Char String--- ExitcodeT (Identity (Left ('x',99)))--- >>> exitfailure 'x' 99 >>- \_ -> exitfailure 'y' 88 :: ExitcodeT Identity Char ()--- ExitcodeT (Identity (Left ('x',99)))--- >>> let loop = loop in exitfailure0 99 >>- loop :: ExitcodeT0 Identity--- ExitcodeT (Identity (Left ((),99)))-instance Monad f => Bind (ExitcodeT f e) where-  (>>-) =-    (>>=)--instance Monad f => Monad (ExitcodeT f e) where-  return =-    pure-  ExitcodeT x >>= f =-    ExitcodeT-      (x >>= either (pure . Left) (runExitcodeT . f))---- |------ >>> exitsuccess "abc" <!> exitsuccess "def" :: ExitcodeT Identity () String--- ExitcodeT (Identity (Right "abc"))--- >>> exitsuccess "abc" <!> exitcodeValue () 99 "def" :: ExitcodeT Identity () String--- ExitcodeT (Identity (Right "abc"))--- >>> exitcodeValue 'x' 99 "abc" <!> exitsuccess "def" :: ExitcodeT Identity Char String--- ExitcodeT (Identity (Right "def"))--- >>> exitcodeValue 'x' 99 "abc" <!> exitcodeValue 'y' 88 "def" :: ExitcodeT Identity Char String--- ExitcodeT (Identity (Left ('y',88)))-instance Monad f => Alt (ExitcodeT f e) where-  ExitcodeT a <!> ExitcodeT b =-    ExitcodeT (a >>= either (const b) (pure a))---- |------ >>> exitsuccess "abc" <> exitsuccess "def" :: ExitcodeT Identity () String--- ExitcodeT (Identity (Right "abcdef"))--- >>> exitsuccess "abc" <> exitcodeValue () 99 "def" :: ExitcodeT Identity () String--- ExitcodeT (Identity (Right "abc"))--- >>> exitcodeValue 'x' 99 "abc" <> exitsuccess "def" :: ExitcodeT Identity Char String--- ExitcodeT (Identity (Right "def"))--- >>> exitcodeValue 'x' 99 "abc" <> exitcodeValue 'y' 88 "def" :: ExitcodeT Identity Char String--- ExitcodeT (Identity (Left ('y',88)))-instance (Semigroup a, Applicative f) => Semigroup (ExitcodeT f e a) where-  ExitcodeT a <> ExitcodeT b =-    let jn (Left _) x  = x-        jn x (Left _) = x-        jn (Right a1) (Right a2) = Right (a1 <> a2)-    in  ExitcodeT (liftA2 jn a b)---- |------ >>> mempty :: ExitcodeT Identity () String--- ExitcodeT (Identity (Right ""))-instance (Monoid a, Applicative f) => Monoid (ExitcodeT f e a) where-  mempty =-    ExitcodeT (pure (Right mempty))---- |------ >>> duplicated (exitfailure0 0) :: ExitcodeT Identity () (ExitcodeT0 Identity)--- ExitcodeT (Identity (Right (ExitcodeT (Identity (Right ())))))--- >>> duplicated (exitfailure0 99) :: ExitcodeT Identity () (ExitcodeT0 Identity)--- ExitcodeT (Identity (Right (ExitcodeT (Identity (Left ((),99))))))--- >>> duplicated (exitsuccess "abc") :: ExitcodeT Identity () (ExitcodeT Identity () String)--- ExitcodeT (Identity (Right (ExitcodeT (Identity (Right "abc")))))-instance Extend f => Extend (ExitcodeT f e) where-  duplicated (ExitcodeT x) =-    ExitcodeT (extended (Right . ExitcodeT) x)--instance (Eq1 f, Eq e, Eq a) => Eq (ExitcodeT f e a) where-  ExitcodeT a == ExitcodeT b =-    a `eq1` b--instance (Eq1 f, Eq e) => Eq1 (ExitcodeT f e) where-  liftEq f (ExitcodeT a) (ExitcodeT b) =-    liftEq (liftEq f) a b--instance (Ord1 f, Ord e, Ord a) => Ord (ExitcodeT f e a) where-  ExitcodeT a `compare` ExitcodeT b =-    a `compare1` b--instance (Ord1 f, Ord e) => Ord1 (ExitcodeT f e) where-  liftCompare f (ExitcodeT a) (ExitcodeT b) =-    liftCompare (liftCompare f) a b--instance (Show1 f, Show e, Show a) => Show (ExitcodeT f e a) where-  showsPrec d (ExitcodeT m) =-    showsUnaryWith showsPrec1 "ExitcodeT" d m--instance (Show1 f, Show e) => Show1 (ExitcodeT f e) where-  liftShowsPrec sp sl d (ExitcodeT fa) =-    let showsPrecF = liftA2 liftShowsPrec (uncurry liftShowsPrec) (uncurry liftShowList) (sp, sl)-    in showsUnaryWith showsPrecF "ExitcodeT" d fa--instance Foldable f => Foldable (ExitcodeT f e) where-  foldMap f (ExitcodeT x) =-    foldMap (foldMap f) x---- |------ >>> traverse (\x -> x) [exitfailure 'x' 99] :: ExitcodeT Identity Char [()]--- ExitcodeT (Identity (Left ('x',99)))--- >>> traverse (\x -> x) [exitfailure 'x' 99, exitsuccess0] :: ExitcodeT Identity Char [()]--- ExitcodeT (Identity (Left ('x',99)))--- >>> traverse (\x -> x) [exitfailure 'x' 99, exitsuccess0, exitfailure 'y' 88] :: ExitcodeT Identity Char [()]--- ExitcodeT (Identity (Left ('x',99)))--- >>> traverse (\x -> x) [exitsuccess0, exitfailure 'x' 88] :: ExitcodeT Identity Char [()]--- ExitcodeT (Identity (Left ('x',88)))--- >>> traverse (\x -> x) [exitsuccess0] :: ExitcodeT Identity () [()]--- ExitcodeT (Identity (Right [()]))-instance Traversable f => Traversable (ExitcodeT f e) where-  traverse f (ExitcodeT x) =-    ExitcodeT <$> traverse (traverse f) x--instance MonadIO f => MonadIO (ExitcodeT f e) where-  liftIO io =-    ExitcodeT (Right <$> liftIO io)--liftExitcode ::-  Functor f =>-  f a-  -> ExitcodeT f e a-liftExitcode x =-  ExitcodeT (Right <$> x)--liftExitcodeFailure ::-  Functor f =>-  f (e, Int)-  -> a-  -> ExitcodeT f e a-liftExitcodeFailure x a =-  ExitcodeT ((\(e, n) -> bool (Left (e, n)) (Right a) (n == 0)) <$> x)--liftExitcodeFailure0 ::-  Functor f =>-  f Int-  -> ExitcodeT0 f-liftExitcodeFailure0 x =-  liftExitcodeFailure (((),) <$> x) ()---- |------ If the given exitcode is success (0), return a failure and make the exitcode negative one (-1).-liftExitFailureNeg1 ::-  Functor f =>-  f (e, Int)-  -> ExitcodeT f e a-liftExitFailureNeg1 x =-  ExitcodeT ((\(e, n) -> Left (e, bool n (-1) (n == 0))) <$> x)--hoistExitcode ::-  (forall x. f x -> g x)-  -> ExitcodeT f e a-  -> ExitcodeT g e a-hoistExitcode nat (ExitcodeT x) =-  ExitcodeT (nat x)--embedExitcode ::-  Functor g =>-  (forall x. f x -> ExitcodeT g e x)-  -> ExitcodeT f e a-  -> ExitcodeT g e a-embedExitcode nat (ExitcodeT x) =-  ExitcodeT (join <$> runExitcodeT (nat x))--instance MonadReader r f => MonadReader r (ExitcodeT f e) where-  ask =-    liftExitcode ask-  local f (ExitcodeT m) =-    ExitcodeT (local f m)---- |------ >>> writer ('x', "abc") :: ExitcodeT ((,) String) () Char--- ExitcodeT ("abc",Right 'x')--- >>> listen (exitfailure 'x' 99 :: ExitcodeT ((,) String) Char ())--- ExitcodeT ("",Left ('x',99))--- >>> listen (exitsuccess 99 :: ExitcodeT ((,) String) () Int)--- ExitcodeT ("",Right (99,""))--- >>> tell "abc" :: ExitcodeT0 ((,) String)--- ExitcodeT ("abc",Right ())--- >>> pass (exitsuccess ('x', reverse)) :: ExitcodeT ((,) String) () Char--- ExitcodeT ("",Right 'x')--- >>> pass (('x', reverse) <$ (exitfailure 'x' 99 :: ExitcodeT ((,) String) Char ()))--- ExitcodeT ("",Left ('x',99))-instance MonadWriter w f => MonadWriter w (ExitcodeT f e) where-  writer t =-    ExitcodeT . fmap pure $ writer t-  listen (ExitcodeT m) =-    ExitcodeT ((\(e, w) -> (,w) <$> e) <$> listen m)-  tell =-    ExitcodeT . fmap Right . tell-  pass e =-    do  ((a, f), w) <- listen e-        tell (f w)-        pure a--instance MonadState s f => MonadState s (ExitcodeT f e) where-  get =-    ExitcodeT (fmap Right get)-  put =-    ExitcodeT . fmap Right . put---- |------ >>> throwError 99 :: ExitcodeT (Either Int) () String--- ExitcodeT (Left 99)--- >>> catchError exitsuccess0 (exitfailure 'x') :: ExitcodeT (Either Int) Char ()--- ExitcodeT (Right (Right ()))--- >>> catchError (exitfailure 'x' 99) (\_ -> exitsuccess0) :: ExitcodeT (Either Int) Char ()--- ExitcodeT (Right (Left ('x',99)))--- >>> catchError (exitfailure 'x' 99) (exitfailure 'y') :: ExitcodeT (Either Int) Char ()--- ExitcodeT (Right (Left ('x',99)))--- >>> catchError exitsuccess0 (\_ -> exitsuccess0) :: ExitcodeT0 (Either Int)--- ExitcodeT (Right (Right ()))-instance MonadError e f => MonadError e (ExitcodeT f e') where-  throwError =-    ExitcodeT . fmap Right . throwError-  catchError (ExitcodeT f) h =-     ExitcodeT (catchError f (runExitcodeT . h))--instance MonadRWS r w s f => MonadRWS r w s (ExitcodeT f e)---- Given the embedded `Either` we can only handle computations that use `Either`.--- This code taken from the ExceptT instance:---   https://hackage.haskell.org/package/transformers-0.5.4.0/docs/src/Control.Monad.Trans.Except.html#line-237-instance MonadCont f => MonadCont (ExitcodeT f e) where-  callCC =-    let liftCallCC callCC' f =-          ExitcodeT . callCC' $-            \c -> runExitcodeT (f (ExitcodeT . c . Right))-    in  liftCallCC callCC--instance Functor f => Bifunctor (ExitcodeT f) where-  bimap f g (ExitcodeT x) =-    ExitcodeT (fmap (bimap (over _1 f) g) x)--instance Foldable f => Bifoldable (ExitcodeT f) where-  bifoldMap f g (ExitcodeT x) =-    foldMap (bifoldMap (f . view _1) g) x--instance Traversable f => Bitraversable (ExitcodeT f) where-  bitraverse f g (ExitcodeT x) =-    ExitcodeT <$> traverse (bitraverse (\(a, n) -> (, n) <$> f a) g) x--type ExitcodeT1 f a =-  ExitcodeT f a a--type Exitcode1 a =-  ExitcodeT1 Identity a---- | Construct an exitcode with an associated value.------ >>> exitcode1 99 "abc" :: ExitcodeT1 Identity String--- ExitcodeT (Identity (Left ("abc",99)))--- >>> exitcode1 0 "abc" :: ExitcodeT1 Identity String--- ExitcodeT (Identity (Right "abc"))-exitcode1 ::-  Applicative f =>-  Int-  -> a-  -> ExitcodeT1 f a-exitcode1 n a =-  exitcodeValue a n a---- | Extract either the non-zero value or the success value.------ >>> runExitcodeT1 exitsuccess0--- Right ()--- >>> runExitcodeT1 (exitfailure0 99) :: Identity (Either ((), Int) ())--- Identity (Left ((),99))--- >>> runExitcodeT1 (exitcode1 0 "abc") :: Identity (Either (String, Int) String)--- Identity (Right "abc")--- >>> runExitcodeT1 (exitcode1 99 "abc") :: Identity (Either (String, Int) String)--- Identity (Left ("abc",99))-runExitcodeT1 ::-  ExitcodeT1 f a-  -> f (Either (a, Int) a)-runExitcodeT1 (ExitcodeT x) =-  x---- | Extract either the non-zero value or the success value.------ >>> runExitcode1 exitsuccess0--- Right ()--- >>> runExitcode1 (exitfailure0 99)--- Left ((),99)--- >>> runExitcode1 (exitcode1 0 "abc")--- Right "abc"--- >>> runExitcode1 (exitcode1 99 "abc")--- Left ("abc",99)-runExitcode1 ::-  Exitcode1 a-  -> Either (a, Int) a-runExitcode1 =-  runIdentity . runExitcodeT1---- | Try the IO action producing the exitcode, possibly throwing an exception.-tryExitcode ::-  Exception e' =>-  ExitcodeT IO e a-  -> ExitcodeT (ExceptT e' IO) e a-tryExitcode (ExitcodeT x) =-  ExitcodeT (ExceptT (try x))+{-# OPTIONS_GHC -Wall #-} --- | Try the IO action producing the exitcode, possibly throwing an exception.-liftTryExitcode ::-  Exception e' =>-  IO a-  -> ExitcodeT (ExceptT e' IO) e a-liftTryExitcode x =-  ExitcodeT (ExceptT (fmap (fmap Right) (try x)))+module Control.Exitcode+  ( module Control.Exitcode.Exitcode,+    module Control.Exitcode.Optics,+  )+where --- | A lens to the value associated with an exitcode.------ >>> view _Exitcode1 (exitcode1 0 "abc")--- "abc"--- >>> view _Exitcode1 (exitcode1 99 "abc")--- "abc"--- >>> view _Exitcode1 (exitcodeValue "abc" 0 "def")--- "def"--- >>> view _Exitcode1 (exitcodeValue "abc" 99 "def")--- "abc"--- >>> over _Exitcode1 reverse (exitcode1 0 "abc")--- ExitcodeT (Identity (Right "cba"))--- >>> over _Exitcode1 reverse (exitcode1 99 "abc")--- ExitcodeT (Identity (Left ("cba",99)))--- >>> over _Exitcode1 reverse (exitcodeValue "abc" 0 "def")--- ExitcodeT (Identity (Right "fed"))--- >>> over _Exitcode1 reverse (exitcodeValue "abc" 99 "def")--- ExitcodeT (Identity (Left ("cba",99)))-_Exitcode1 ::-  Lens-    (Exitcode1 a)-    (Exitcode1 a')-    a-    a'-_Exitcode1 f =-  either-    (\(a, n) -> fmap (exitcode1 n) (f a))-    (fmap (exitcode1 0) . f)-    . runExitcode1+import Control.Exitcode.Exitcode+import Control.Exitcode.Optics
+ src/Control/Exitcode/Exitcode.hs view
@@ -0,0 +1,1156 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TupleSections #-}+-- Required for instances like MonadReader r (Exitcode e f) where the+-- constraint MonadReader r f does not structurally decrease.+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# OPTIONS_GHC -Wall #-}++module Control.Exitcode.Exitcode+  ( -- * Types+    Exitcode (..),+    Exitcode',+    ExitcodeBifunctor (..),+    ExitcodeBifunctor',++    -- * Construction+    mkExitcode,+    mkExitcode',+    mkExitSuccess,+    mkExitSuccess',+    mkExitFailure,+    mkExitFailure',+    mkExitFailure1,+    mkExitFailure1',+    mkExitFailure_1,+    mkExitFailure_1',+    fromExitCode,+    fromExitCode',+    toExitCode,+    toExitCode',+    hoistExitcode,+    embedExitcode,+    bimapExitcode,++    -- * Extraction+    runExitcode,+    maybeExitcode,+    maybeExitcode',++    -- * Exceptions+    tryExitcode,+    liftTryExitcode,++    -- * Optics+    exitCode,+    _Exitcode1,+    _Exitcode1',+    _ExitFailure,+    _ExitFailure',+    _ExitFailureCode,+    _ExitFailureCode',+    _ExitFailureValue,+    _ExitFailureValue',+    _ExitSuccess,+    _ExitSuccess',+  )+where++import Control.Applicative (Applicative (pure, (<*>)))+import Control.DeepSeq (NFData (rnf), NFData1 (liftRnf))+import Control.Exception (Exception, try)+import Control.Lens (FoldableWithIndex (ifoldMap), FunctorWithIndex (imap), Iso, Lens, Prism, Prism', Traversal, Traversal', TraversableWithIndex (itraverse), iso, preview, prism, prism', review, _Wrapped)+import Control.Monad (Monad ((>>=)), join)+import Control.Monad.Cont.Class (MonadCont (..))+import Control.Monad.Error.Class (MonadError (..))+import Control.Monad.Except (ExceptT (..))+import Control.Monad.Fix (MonadFix (mfix))+import Control.Monad.IO.Class (MonadIO (..))+import Control.Monad.RWS.Class (MonadRWS)+import Control.Monad.Reader (MonadReader (ask, local), asks)+import Control.Monad.State.Lazy (MonadState (get, put))+import Control.Monad.Trans.Class (MonadTrans (lift))+import Control.Monad.Trans.Maybe (MaybeT (MaybeT))+import Control.Monad.Writer.Class (MonadWriter (..))+import Data.Bifoldable (Bifoldable (bifoldMap))+import Data.Bifunctor (Bifunctor (bimap))+import Data.Bitraversable (Bitraversable (bitraverse))+import Data.Either (Either (..), either)+import Data.Eq (Eq ((==)))+import Data.Foldable (Foldable (foldMap, toList))+import Data.Function (const, id, ($), (.))+import Data.Functor (Functor (fmap), (<$>))+import Data.Functor.Alt (Alt ((<!>)))+import Data.Functor.Apply (Apply ((<.>)))+import Data.Functor.Bind (Bind ((>>-)))+import Data.Functor.Bind.Trans (BindTrans (..))+import Data.Functor.Classes+  ( Eq1 (liftEq),+    Ord1 (liftCompare),+    Show1 (liftShowList, liftShowsPrec),+  )+import Data.Functor.Extend (Extend (duplicated, extended))+import Data.Functor.Identity (Identity (Identity, runIdentity))+import Data.Int (Int)+import Data.Maybe (Maybe (Just, Nothing))+import Data.Monoid (Monoid (mempty))+import Data.Ord (Ord (compare), (>))+import Data.Semigroup (Semigroup ((<>)))+import Data.Traversable (Traversable (traverse), mapAccumL)+import Data.Tuple (fst, snd)+import GHC.Generics (Generic)+import GHC.Show (Show (showsPrec), showParen, showString)+import Natural (NotZero, _NotZero, notZeroOr)+import Prelude (seq)+import System.Exit (ExitCode (ExitFailure, ExitSuccess))+import System.IO (IO)++-- $setup+-- >>> import Prelude+-- >>> import Control.Lens+-- >>> import Natural+-- >>> let nz1 = positiveNotZero one'+-- >>> let nz2 = positiveNotZero (successor1' one')++-- | An exit code status where failing with a value @0@ cannot be represented.+--+-- Wraps @f (Either (e, NotZero) a)@ where the @NotZero@ in the @Left@ branch+-- is a proven non-zero integer.+newtype Exitcode e f a+  = Exitcode (f (Either (e, NotZero) a))+  deriving stock (Generic)++-- | @Exitcode@ specialised to @Identity@.+type Exitcode' e a =+  Exitcode e Identity a++-- * Extraction++-- | Extract the underlying @f (Either (e, NotZero) a)@.+--+-- >>> runExitcode (mkExitSuccess' "abc")+-- Identity (Right "abc")+-- >>> runExitcode (mkExitFailure1' 'x')+-- Identity (Left ('x',NotZero True (Positive 1)))+{-# INLINE runExitcode #-}+runExitcode ::+  Exitcode e f a ->+  f (Either (e, NotZero) a)+runExitcode (Exitcode x) =+  x++-- | Extract the exit code as @Maybe NotZero@: @Nothing@ for success, @Just n@ for failure.+--+-- >>> maybeExitcode (mkExitSuccess (Identity ())) :: Identity (Maybe NotZero)+-- Identity Nothing+-- >>> maybeExitcode (mkExitFailure1 (Identity ())) :: Identity (Maybe NotZero)+-- Identity (Just (NotZero True (Positive 1)))+{-# INLINE maybeExitcode #-}+maybeExitcode ::+  (Functor f) =>+  Exitcode e f a ->+  f (Maybe NotZero)+maybeExitcode (Exitcode x) =+  fmap (either (Just . snd) (const Nothing)) x++-- | @maybeExitcode@ specialised to @Identity@.+--+-- >>> maybeExitcode' (mkExitSuccess' ())+-- Nothing+-- >>> maybeExitcode' (mkExitFailure1' ())+-- Just (NotZero True (Positive 1))+{-# INLINE maybeExitcode' #-}+maybeExitcode' ::+  Exitcode' e a ->+  Maybe NotZero+maybeExitcode' (Exitcode x) =+  either (Just . snd) (const Nothing) (runIdentity x)++-- * Optics++-- | Iso between @f ExitCode@ and @Exitcode () (MaybeT f) ()@.+--+-- @ExitFailure 0@ maps to @MaybeT Nothing@ (neither success nor failure).+-- @ExitSuccess@ maps to a success exitcode.+-- @ExitFailure n@ (where @n /= 0@) maps to a failure exitcode.+--+-- >>> import Control.Monad.Trans.Maybe+-- >>> view exitCode (Identity ExitSuccess)+-- Exitcode (MaybeT (Identity (Just (Right ()))))+-- >>> view exitCode (Identity (ExitFailure 99))+-- Exitcode (MaybeT (Identity (Just (Left ((),NotZero True (Positive 99))))))+-- >>> view exitCode (Identity (ExitFailure 0))+-- Exitcode (MaybeT (Identity Nothing))+-- >>> review exitCode (mkExitSuccess (MaybeT (Identity (Just ()))))+-- Identity ExitSuccess+-- >>> review exitCode (mkExitFailure1 (MaybeT (Identity (Just ()))))+-- Identity (ExitFailure 1)+{-# INLINE exitCode #-}+exitCode ::+  (Functor f, Functor g) =>+  Iso+    (f ExitCode)+    (g ExitCode)+    (Exitcode () (MaybeT f) ())+    (Exitcode () (MaybeT g) ())+exitCode =+  iso+    ( Exitcode+        . MaybeT+        . fmap+          ( \case+              ExitSuccess -> Just (Right ())+              ExitFailure n -> fmap (Left . ((),)) (preview _NotZero n)+          )+    )+    ( \(Exitcode (MaybeT x)) ->+        fmap+          ( \case+              Just (Right ()) -> ExitSuccess+              Nothing -> ExitFailure 0+              Just (Left ((), nz)) -> ExitFailure (review _NotZero nz)+          )+          x+    )++-- | Lens into the value of an @Exitcode' a a@, regardless of success or failure.+-- The exit code is preserved.+--+-- >>> over _Exitcode1 reverse (mkExitcode' "abc" nz1 :: Exitcode' String String)+-- Exitcode (Identity (Left ("cba",NotZero True (Positive 1))))+-- >>> over _Exitcode1 reverse (mkExitSuccess' "def")+-- Exitcode (Identity (Right "fed"))+{-# INLINE _Exitcode1 #-}+_Exitcode1 ::+  Lens+    (Exitcode' a a)+    (Exitcode' a' a')+    a+    a'+_Exitcode1 g (Exitcode (Identity x)) =+  fmap+    (\a' -> Exitcode (Identity (either (\(_, n) -> Left (a', n)) (const (Right a')) x)))+    (g (either fst id x))++-- | @_Exitcode1@ generalised to @Traversable f@.+--+-- >>> over _Exitcode1' (fmap reverse) (mkExitcode (Identity "abc") (Identity nz1) :: Exitcode String Identity String)+-- Exitcode (Identity (Left ("cba",NotZero True (Positive 1))))+-- >>> over _Exitcode1' (fmap reverse) (mkExitSuccess (Identity "def"))+-- Exitcode (Identity (Right "fed"))+{-# INLINE _Exitcode1' #-}+_Exitcode1' ::+  (Traversable f) =>+  Traversal' (Exitcode a f a) (f a)+_Exitcode1' g (Exitcode x) =+  fmap+    ( \fa' ->+        let (_, result) =+              mapAccumL+                ( \as' struct -> case as' of+                    (a' : rest) -> (rest, either (\(_, n) -> Left (a', n)) (const (Right a')) struct)+                    [] -> ([], struct)+                )+                (toList fa')+                x+         in Exitcode result+    )+    (g (fmap (either fst id) x))++-- | Prism into all-failure exitcodes.+--+-- >>> preview _ExitFailure (mkExitFailure1' 'x' :: Exitcode' Char ())+-- Just (Identity ('x',NotZero True (Positive 1)))+-- >>> preview _ExitFailure (mkExitSuccess' () :: Exitcode' Char ())+-- Nothing+{-# INLINE _ExitFailure #-}+_ExitFailure :: (Traversable f) => Prism' (Exitcode e f a) (f (e, NotZero))+_ExitFailure =+  prism'+    (Exitcode . fmap Left)+    (\(Exitcode x) -> traverse (either Just (const Nothing)) x)++-- | Type-changing prism into the failure case, specialised to @Identity@.+--+-- >>> preview _ExitFailure' (mkExitFailure1' 'x' :: Exitcode' Char ())+-- Just ('x',NotZero True (Positive 1))+-- >>> preview _ExitFailure' (mkExitSuccess' () :: Exitcode' Char ())+-- Nothing+-- >>> review _ExitFailure' ('y', nz2) :: Exitcode' Char ()+-- Exitcode (Identity (Left ('y',NotZero True (Positive 2))))+{-# INLINE _ExitFailure' #-}+_ExitFailure' :: Prism (Exitcode' e a) (Exitcode' e' a) (e, NotZero) (e', NotZero)+_ExitFailure' =+  prism+    (\(e', nz) -> Exitcode (Identity (Left (e', nz))))+    (\(Exitcode (Identity x)) -> case x of+      Left (e, nz) -> Right (e, nz)+      Right a -> Left (Exitcode (Identity (Right a))))++-- | Traversal into the @NotZero@ exit code values when all elements are failures.+--+-- >>> over _ExitFailureCode' (const nz1) (mkExitFailure' nz2 'x')+-- Exitcode (Identity (Left ('x',NotZero True (Positive 1))))+{-# INLINE _ExitFailureCode #-}+_ExitFailureCode :: (Traversable f) => Traversal' (Exitcode e f a) (f NotZero)+_ExitFailureCode g (Exitcode x) =+  case traverse (either Just (const Nothing)) x of+    Nothing -> pure (Exitcode x)+    Just pairs ->+      let rebuild newNZs =+            let (_, result) =+                  mapAccumL+                    ( \ns (e, nz) -> case ns of+                        n : rest -> (rest, (e, n))+                        [] -> ([], (e, nz))+                    )+                    (toList newNZs)+                    pairs+             in Exitcode (fmap Left result)+       in rebuild <$> g (fmap snd pairs)++-- | @_ExitFailureCode@ specialised to @Identity@.+{-# INLINE _ExitFailureCode' #-}+_ExitFailureCode' :: Traversal' (Exitcode' e a) NotZero+_ExitFailureCode' = _ExitFailureCode . _Wrapped++-- | Traversal into the error values when all elements are failures.+--+-- >>> over _ExitFailureValue' (const 'y') (mkExitFailure1' 'x')+-- Exitcode (Identity (Left ('y',NotZero True (Positive 1))))+-- >>> over _ExitFailureValue' (const 'y') (mkExitSuccess' () :: Exitcode' Char ())+-- Exitcode (Identity (Right ()))+{-# INLINE _ExitFailureValue #-}+_ExitFailureValue :: (Traversable f) => Traversal' (Exitcode e f a) (f e)+_ExitFailureValue g (Exitcode x) =+  case traverse (either Just (const Nothing)) x of+    Nothing -> pure (Exitcode x)+    Just pairs ->+      let rebuild newEs =+            let (_, result) =+                  mapAccumL+                    ( \es (e, nz) -> case es of+                        e' : rest -> (rest, (e', nz))+                        [] -> ([], (e, nz))+                    )+                    (toList newEs)+                    pairs+             in Exitcode (fmap Left result)+       in rebuild <$> g (fmap fst pairs)++-- | @_ExitFailureValue@ specialised to @Identity@.+{-# INLINE _ExitFailureValue' #-}+_ExitFailureValue' :: Traversal (Exitcode' e a) (Exitcode' e' a) e e'+_ExitFailureValue' g (Exitcode (Identity x)) =+  case x of+    Left (e, nz) -> fmap (\e' -> Exitcode (Identity (Left (e', nz)))) (g e)+    Right a -> pure (Exitcode (Identity (Right a)))++-- | Prism into all-success exitcodes.+--+-- >>> preview _ExitSuccess (mkExitSuccess' "abc" :: Exitcode' () String)+-- Just (Identity "abc")+-- >>> preview _ExitSuccess (mkExitFailure1' () :: Exitcode' () String)+-- Nothing+{-# INLINE _ExitSuccess #-}+_ExitSuccess :: (Traversable f) => Prism' (Exitcode e f a) (f a)+_ExitSuccess =+  prism'+    (Exitcode . fmap Right)+    (\(Exitcode x) -> traverse (either (const Nothing) Just) x)++-- | @_ExitSuccess@ specialised to @Identity@.+--+-- >>> preview _ExitSuccess' (mkExitSuccess' "abc" :: Exitcode' () String)+-- Just "abc"+-- >>> preview _ExitSuccess' (mkExitFailure1' () :: Exitcode' () String)+-- Nothing+{-# INLINE _ExitSuccess' #-}+_ExitSuccess' :: Prism (Exitcode' e a) (Exitcode' e a') a a'+_ExitSuccess' =+  prism+    (Exitcode . Identity . Right)+    ( \(Exitcode (Identity x)) -> case x of+        Right a -> Right a+        Left (e, i) -> Left (Exitcode (Identity (Left (e, i))))+    )++-- | Construct a failure exitcode with an error value and a non-zero exit code.+--+-- >>> mkExitcode (Identity 'x') (Identity nz1) :: Exitcode' Char ()+-- Exitcode (Identity (Left ('x',NotZero True (Positive 1))))+{-# INLINE mkExitcode #-}+mkExitcode :: (Applicative f) => f e -> f NotZero -> Exitcode e f a+mkExitcode e nz = Exitcode ((\e' nz' -> Left (e', nz')) <$> e <*> nz)++-- | @mkExitcode@ specialised to @Identity@.+--+-- >>> mkExitcode' 'x' nz1 :: Exitcode' Char ()+-- Exitcode (Identity (Left ('x',NotZero True (Positive 1))))+{-# INLINE mkExitcode' #-}+mkExitcode' :: e -> NotZero -> Exitcode' e a+mkExitcode' e nz = mkExitcode (Identity e) (Identity nz)++-- | Construct a success exitcode.+--+-- >>> mkExitSuccess (Identity "abc") :: Exitcode' () String+-- Exitcode (Identity (Right "abc"))+{-# INLINE mkExitSuccess #-}+mkExitSuccess :: (Functor f) => f a -> Exitcode e f a+mkExitSuccess = Exitcode . fmap Right++-- | @mkExitSuccess@ specialised to @Identity@.+--+-- >>> mkExitSuccess' "abc" :: Exitcode' () String+-- Exitcode (Identity (Right "abc"))+{-# INLINE mkExitSuccess' #-}+mkExitSuccess' :: a -> Exitcode' e a+mkExitSuccess' = mkExitSuccess . Identity++-- | Construct a failure exitcode with a proven non-zero exit code.+--+-- >>> mkExitFailure (Identity nz1) (Identity 'x') :: Exitcode' Char ()+-- Exitcode (Identity (Left ('x',NotZero True (Positive 1))))+{-# INLINE mkExitFailure #-}+mkExitFailure :: (Applicative f) => f NotZero -> f e -> Exitcode e f a+mkExitFailure n e = Exitcode ((\n' e' -> Left (e', n')) <$> n <*> e)++-- | @mkExitFailure@ specialised to @Identity@.+--+-- >>> mkExitFailure' nz1 'x' :: Exitcode' Char ()+-- Exitcode (Identity (Left ('x',NotZero True (Positive 1))))+{-# INLINE mkExitFailure' #-}+mkExitFailure' :: NotZero -> e -> Exitcode' e a+mkExitFailure' n e = mkExitFailure (Identity n) (Identity e)++-- | Construct a failure exitcode with exit code @1@.+--+-- >>> mkExitFailure1 (Identity 'x') :: Exitcode' Char ()+-- Exitcode (Identity (Left ('x',NotZero True (Positive 1))))+{-# INLINE mkExitFailure1 #-}+mkExitFailure1 :: (Functor f) => f e -> Exitcode e f a+mkExitFailure1 = Exitcode . fmap (\e' -> Left (e', notZeroOr (1 :: Int)))++-- | @mkExitFailure1@ specialised to @Identity@.+--+-- >>> mkExitFailure1' 'x' :: Exitcode' Char ()+-- Exitcode (Identity (Left ('x',NotZero True (Positive 1))))+{-# INLINE mkExitFailure1' #-}+mkExitFailure1' :: e -> Exitcode' e a+mkExitFailure1' = mkExitFailure1 . Identity++-- | Construct a failure exitcode with exit code @-1@.+--+-- >>> mkExitFailure_1 (Identity 'x') :: Exitcode' Char ()+-- Exitcode (Identity (Left ('x',NotZero False (Positive 1))))+{-# INLINE mkExitFailure_1 #-}+mkExitFailure_1 :: (Functor f) => f e -> Exitcode e f a+mkExitFailure_1 = Exitcode . fmap (\e' -> Left (e', notZeroOr (-1 :: Int)))++-- | @mkExitFailure_1@ specialised to @Identity@.+--+-- >>> mkExitFailure_1' 'x' :: Exitcode' Char ()+-- Exitcode (Identity (Left ('x',NotZero False (Positive 1))))+{-# INLINE mkExitFailure_1' #-}+mkExitFailure_1' :: e -> Exitcode' e a+mkExitFailure_1' = mkExitFailure_1 . Identity++-- | Convert from a base @ExitCode@. @ExitFailure 0@ is treated as success.+--+-- >>> fromExitCode (Identity ExitSuccess)+-- Exitcode (Identity (Right ()))+-- >>> fromExitCode (Identity (ExitFailure 99))+-- Exitcode (Identity (Left ((),NotZero True (Positive 99))))+-- >>> fromExitCode (Identity (ExitFailure 0))+-- Exitcode (Identity (Right ()))+{-# INLINE fromExitCode #-}+fromExitCode ::+  (Functor f) =>+  f ExitCode ->+  Exitcode () f ()+fromExitCode =+  Exitcode+    . fmap+      ( \case+          ExitSuccess -> Right ()+          ExitFailure n -> case preview _NotZero n of+            Just nz -> Left ((), nz)+            Nothing -> Right ()+      )++-- | @fromExitCode@ specialised to @Identity@.+--+-- >>> fromExitCode' ExitSuccess+-- Exitcode (Identity (Right ()))+-- >>> fromExitCode' (ExitFailure 99)+-- Exitcode (Identity (Left ((),NotZero True (Positive 99))))+-- >>> fromExitCode' (ExitFailure 0)+-- Exitcode (Identity (Right ()))+{-# INLINE fromExitCode' #-}+fromExitCode' ::+  ExitCode ->+  Exitcode' () ()+fromExitCode' =+  fromExitCode . Identity++-- | Convert an exitcode back to @f ExitCode@.+--+-- >>> toExitCode (mkExitSuccess (Identity ()))+-- Identity ExitSuccess+-- >>> toExitCode (mkExitFailure1 (Identity ()))+-- Identity (ExitFailure 1)+{-# INLINE toExitCode #-}+toExitCode ::+  (Functor f) =>+  Exitcode () f () ->+  f ExitCode+toExitCode (Exitcode x) =+  fmap (either (\((), nz) -> ExitFailure (review _NotZero nz)) (const ExitSuccess)) x++-- | @toExitCode@ specialised to @Identity@.+--+-- >>> toExitCode' (mkExitSuccess' ())+-- ExitSuccess+-- >>> toExitCode' (mkExitFailure1' ())+-- ExitFailure 1+{-# INLINE toExitCode' #-}+toExitCode' ::+  Exitcode' () () ->+  ExitCode+toExitCode' =+  runIdentity . toExitCode++-- | Apply a natural transformation to the base functor.+--+-- >>> hoistExitcode (Just . runIdentity) (mkExitSuccess' "abc") :: Exitcode () Maybe String+-- Exitcode (Just (Right "abc"))+{-# INLINE hoistExitcode #-}+hoistExitcode ::+  (forall x. f x -> g x) ->+  Exitcode e f a ->+  Exitcode e g a+hoistExitcode nat (Exitcode x) =+  Exitcode (nat x)++-- | Embed a natural transformation that returns an @Exitcode@.+--+-- >>> embedExitcode (\(Identity a) -> mkExitSuccess (Just a)) (mkExitSuccess' "abc") :: Exitcode () Maybe String+-- Exitcode (Just (Right "abc"))+-- >>> embedExitcode (\(Identity a) -> mkExitSuccess (Just a)) (mkExitFailure1' ()) :: Exitcode () Maybe ()+-- Exitcode (Just (Left ((),NotZero True (Positive 1))))+{-# INLINE embedExitcode #-}+embedExitcode ::+  (Functor g) =>+  (forall x. f x -> Exitcode e g x) ->+  Exitcode e f a ->+  Exitcode e g a+embedExitcode nat (Exitcode x) =+  Exitcode (join <$> runExitcode (nat x))++-- | Map both the error and success values via @Bifunctor@ on @ExitcodeBifunctor@.+--+-- >>> bimapExitcode (+1) (+10) (mkExitFailure1' 5 :: Exitcode' Int Int)+-- Exitcode (Identity (Left (6,NotZero True (Positive 1))))+-- >>> bimapExitcode (+1) (+10) (mkExitSuccess' 5 :: Exitcode' Int Int)+-- Exitcode (Identity (Right 15))+{-# INLINE bimapExitcode #-}+bimapExitcode ::+  (Functor f) =>+  (e -> e') ->+  (a -> a') ->+  Exitcode e f a ->+  Exitcode e' f a'+bimapExitcode f g (Exitcode x) =+  Exitcode (fmap (either (\(e, n) -> Left (f e, n)) (Right . g)) x)++-- * Exceptions++-- | Try the IO action producing the exitcode, catching exceptions into @ExceptT@.+{-# INLINE tryExitcode #-}+tryExitcode ::+  (Exception e') =>+  Exitcode e IO a ->+  Exitcode e (ExceptT e' IO) a+tryExitcode (Exitcode x) =+  Exitcode (ExceptT (try x))++-- | Lift an IO action into @Exitcode (ExceptT e' IO)@, catching exceptions.+{-# INLINE liftTryExitcode #-}+liftTryExitcode ::+  (Exception e') =>+  IO a ->+  Exitcode e (ExceptT e' IO) a+liftTryExitcode x =+  Exitcode (ExceptT (fmap (fmap Right) (try x)))++-- * RULES++{-# INLINE [0] exitcodeMap #-}+exitcodeMap :: (Functor f) => (a -> b) -> Exitcode e f a -> Exitcode e f b+exitcodeMap f (Exitcode x) = Exitcode (fmap (fmap f) x)++{-# INLINE [0] exitcodeFoldMap #-}+exitcodeFoldMap :: (Foldable f, Monoid m) => (a -> m) -> Exitcode e f a -> m+exitcodeFoldMap f (Exitcode x) = foldMap (either (const mempty) f) x++{-# RULES+"exitcodeMap/exitcodeMap" [~0] forall f g xs.+  exitcodeMap f (exitcodeMap g xs) =+    exitcodeMap (f . g) xs+"exitcodeFoldMap/exitcodeMap" [~0] forall f g xs.+  exitcodeFoldMap f (exitcodeMap g xs) =+    exitcodeFoldMap (f . g) xs+  #-}++-- * Exitcode Instances++-- |+--+-- >>> fmap (+1) (mkExitSuccess' 3) :: Exitcode' () Int+-- Exitcode (Identity (Right 4))+-- >>> fmap (+1) (mkExitFailure1' ()) :: Exitcode' () Int+-- Exitcode (Identity (Left ((),NotZero True (Positive 1))))+instance (Functor f) => Functor (Exitcode e f) where+  {-# INLINE fmap #-}+  fmap = exitcodeMap++-- |+--+-- >>> foldMap show (mkExitSuccess' 42) :: String+-- "42"+-- >>> foldMap show (mkExitFailure1' () :: Exitcode' () Int) :: String+-- ""+instance (Foldable f) => Foldable (Exitcode e f) where+  {-# INLINE foldMap #-}+  foldMap = exitcodeFoldMap++-- |+--+-- >>> traverse Just (mkExitSuccess' 42) :: Maybe (Exitcode' () Int)+-- Just (Exitcode (Identity (Right 42)))+-- >>> traverse (const Nothing) (mkExitSuccess' 42) :: Maybe (Exitcode' () Int)+-- Nothing+-- >>> traverse Just (mkExitFailure1' () :: Exitcode' () Int) :: Maybe (Exitcode' () Int)+-- Just (Exitcode (Identity (Left ((),NotZero True (Positive 1)))))+instance (Traversable f) => Traversable (Exitcode e f) where+  {-# INLINE traverse #-}+  traverse f (Exitcode x) =+    Exitcode <$> traverse (either (pure . Left) (fmap Right . f)) x++-- |+--+-- >>> imap (\_ a -> a + 1) (mkExitSuccess' 3) :: Exitcode' () Int+-- Exitcode (Identity (Right 4))+instance (FunctorWithIndex i f) => FunctorWithIndex i (Exitcode e f) where+  {-# INLINE imap #-}+  imap f (Exitcode x) = Exitcode (imap (\i -> fmap (f i)) x)++-- |+--+-- >>> ifoldMap (\_ a -> show a) (mkExitSuccess' 42) :: String+-- "42"+instance (FoldableWithIndex i f) => FoldableWithIndex i (Exitcode e f) where+  {-# INLINE ifoldMap #-}+  ifoldMap f (Exitcode x) = ifoldMap (\i -> either (const mempty) (f i)) x++-- |+--+-- >>> itraverse (\_ a -> Just (a + 1)) (mkExitSuccess' 42) :: Maybe (Exitcode' () Int)+-- Just (Exitcode (Identity (Right 43)))+instance (TraversableWithIndex i f) => TraversableWithIndex i (Exitcode e f) where+  {-# INLINE itraverse #-}+  itraverse f (Exitcode x) = Exitcode <$> itraverse (\i -> either (pure . Left) (fmap Right . f i)) x++-- |+--+-- >>> mkExitSuccess' (+1) <*> mkExitSuccess' 3 :: Exitcode' () Int+-- Exitcode (Identity (Right 4))+-- >>> mkExitFailure1' () <*> mkExitSuccess' 3 :: Exitcode' () Int+-- Exitcode (Identity (Left ((),NotZero True (Positive 1))))+instance (Monad f) => Apply (Exitcode e f) where+  {-# INLINE (<.>) #-}+  Exitcode f <.> Exitcode a =+    Exitcode (f >>= either (pure . Left) (\f' -> fmap (fmap f') a))++-- |+--+-- >>> pure 42 :: Exitcode' () Int+-- Exitcode (Identity (Right 42))+-- >>> mkExitSuccess' (+1) <*> mkExitSuccess' 3 :: Exitcode' () Int+-- Exitcode (Identity (Right 4))+-- >>> mkExitFailure1' () <*> mkExitSuccess' 3 :: Exitcode' () Int+-- Exitcode (Identity (Left ((),NotZero True (Positive 1))))+instance (Monad f) => Applicative (Exitcode e f) where+  {-# INLINE pure #-}+  pure = Exitcode . pure . Right+  {-# INLINE (<*>) #-}+  Exitcode f <*> Exitcode a =+    Exitcode (f >>= either (pure . Left) (\f' -> fmap (fmap f') a))++-- |+--+-- >>> mkExitSuccess' 3 >>- (\x -> mkExitSuccess' (x + 1)) :: Exitcode' () Int+-- Exitcode (Identity (Right 4))+instance (Monad f) => Bind (Exitcode e f) where+  {-# INLINE (>>-) #-}+  (>>-) = (>>=)++-- |+--+-- >>> mkExitSuccess' 3 >>= (\x -> mkExitSuccess' (x + 1)) :: Exitcode' () Int+-- Exitcode (Identity (Right 4))+-- >>> mkExitFailure1' () >>= (\x -> mkExitSuccess' (x + 1)) :: Exitcode' () Int+-- Exitcode (Identity (Left ((),NotZero True (Positive 1))))+instance (Monad f) => Monad (Exitcode e f) where+  {-# INLINE (>>=) #-}+  Exitcode x >>= f =+    Exitcode (x >>= either (pure . Left) (runExitcode . f))++-- |+--+-- >>> import Control.Monad.Fix (mfix)+-- >>> runExitcode (mfix (const (mkExitSuccess' 42)) :: Exitcode' () Int)+-- Identity (Right 42)+-- >>> runExitcode (mfix (const (mkExitFailure1' ())) :: Exitcode' () Int)+-- Identity (Left ((),NotZero True (Positive 1)))+instance (MonadFix f) => MonadFix (Exitcode e f) where+  {-# INLINE mfix #-}+  mfix f = Exitcode (mfix (runExitcode . f . either (const (let a = a in a)) id))++-- |+--+-- >>> mkExitFailure1' () <!> mkExitSuccess' 42 :: Exitcode' () Int+-- Exitcode (Identity (Right 42))+-- >>> mkExitSuccess' 1 <!> mkExitSuccess' 2 :: Exitcode' () Int+-- Exitcode (Identity (Right 1))+instance (Monad f) => Alt (Exitcode e f) where+  {-# INLINE (<!>) #-}+  Exitcode a <!> Exitcode b =+    Exitcode (a >>= either (const b) (pure . Right))++-- |+--+-- >>> mkExitSuccess' "abc" <> mkExitSuccess' "def" :: Exitcode' () String+-- Exitcode (Identity (Right "abcdef"))+-- >>> mkExitSuccess' "abc" <> mkExitFailure1' () :: Exitcode' () String+-- Exitcode (Identity (Right "abc"))+-- >>> mkExitFailure1' () <> mkExitSuccess' "def" :: Exitcode' () String+-- Exitcode (Identity (Right "def"))+-- >>> (mkExitFailure1' () :: Exitcode' () String) <> mkExitFailure_1' ()+-- Exitcode (Identity (Left ((),NotZero False (Positive 1))))+instance (Semigroup a, Monad f) => Semigroup (Exitcode e f a) where+  {-# INLINE (<>) #-}+  Exitcode a <> Exitcode b =+    Exitcode+      ( a+          >>= either+            (\_ -> b >>= either (pure . Left) (pure . Right))+            (\a1 -> b >>= either (\_ -> pure (Right a1)) (\a2 -> pure (Right (a1 <> a2))))+      )++-- |+--+-- >>> mempty :: Exitcode' () String+-- Exitcode (Identity (Right ""))+instance (Monoid a, Monad f) => Monoid (Exitcode e f a) where+  {-# INLINE mempty #-}+  mempty = Exitcode (pure (Right mempty))++-- |+--+-- >>> duplicated (mkExitFailure1' ()) :: Exitcode' () (Exitcode' () ())+-- Exitcode (Identity (Right (Exitcode (Identity (Left ((),NotZero True (Positive 1)))))))+-- >>> duplicated (mkExitSuccess' "abc") :: Exitcode' () (Exitcode' () String)+-- Exitcode (Identity (Right (Exitcode (Identity (Right "abc")))))+instance (Extend f) => Extend (Exitcode e f) where+  {-# INLINE duplicated #-}+  duplicated (Exitcode x) =+    Exitcode (extended (Right . Exitcode) x)++-- |+--+-- >>> mkExitSuccess' 1 == mkExitSuccess' 1 :: Bool+-- True+-- >>> mkExitSuccess' 1 == (mkExitFailure1' () :: Exitcode' () Int) :: Bool+-- False+instance (Eq (f (Either (e, NotZero) a))) => Eq (Exitcode e f a) where+  {-# INLINE (==) #-}+  Exitcode a == Exitcode b = a == b++-- |+--+-- >>> liftEq (==) (mkExitSuccess' 1) (mkExitSuccess' 1 :: Exitcode' () Int)+-- True+-- >>> liftEq (==) (mkExitSuccess' 1) (mkExitSuccess' 2 :: Exitcode' () Int)+-- False+instance (Eq1 f, Eq e) => Eq1 (Exitcode e f) where+  {-# INLINE liftEq #-}+  liftEq f (Exitcode a) (Exitcode b) =+    liftEq (liftEq f) a b++-- |+--+-- >>> compare (mkExitSuccess' 1 :: Exitcode' () Int) (mkExitSuccess' 2)+-- LT+-- >>> compare (mkExitSuccess' 1 :: Exitcode' () Int) (mkExitFailure1' ())+-- GT+instance (Ord (f (Either (e, NotZero) a))) => Ord (Exitcode e f a) where+  {-# INLINE compare #-}+  Exitcode a `compare` Exitcode b = compare a b++-- |+--+-- >>> liftCompare compare (mkExitSuccess' 1) (mkExitSuccess' 2 :: Exitcode' () Int)+-- LT+instance (Ord1 f, Ord e) => Ord1 (Exitcode e f) where+  {-# INLINE liftCompare #-}+  liftCompare f (Exitcode a) (Exitcode b) =+    liftCompare (liftCompare f) a b++-- |+--+-- >>> show (mkExitSuccess' "abc" :: Exitcode' () String)+-- "Exitcode (Identity (Right \"abc\"))"+-- >>> show (mkExitFailure1' 'x' :: Exitcode' Char ())+-- "Exitcode (Identity (Left ('x',NotZero True (Positive 1))))"+instance (Show (f (Either (e, NotZero) a))) => Show (Exitcode e f a) where+  {-# INLINE showsPrec #-}+  showsPrec d (Exitcode m) =+    showParen (d > 10) $+      showString "Exitcode " . showsPrec 11 m++-- |+--+-- >>> liftShowsPrec showsPrec showList 0 (mkExitSuccess' 42 :: Exitcode' () Int) ""+-- "Exitcode (Identity (Right 42))"+instance (Show1 f, Show e) => Show1 (Exitcode e f) where+  {-# INLINE liftShowsPrec #-}+  liftShowsPrec sp sl d (Exitcode fa) =+    showParen (d > 10) $+      showString "Exitcode "+        . liftShowsPrec (liftShowsPrec sp sl) (liftShowList sp sl) 11 fa++instance (NFData1 f, NFData e, NFData a) => NFData (Exitcode e f a) where+  {-# INLINE rnf #-}+  rnf = liftRnf rnf++instance (NFData1 f, NFData e) => NFData1 (Exitcode e f) where+  {-# INLINE liftRnf #-}+  liftRnf r (Exitcode x) = liftRnf rnfEither x+    where+      rnfEither (Right a) = r a+      rnfEither (Left (e, n)) = rnf e `seq` rnf (review _NotZero n :: Int)++-- |+--+-- >>> import Control.Monad.IO.Class (liftIO)+-- >>> runExitcode (liftIO (pure 42) :: Exitcode () IO Int)+-- Right 42+instance (MonadIO f) => MonadIO (Exitcode e f) where+  {-# INLINE liftIO #-}+  liftIO io = Exitcode (Right <$> liftIO io)++-- |+--+-- >>> import Control.Monad.Reader (runReader)+-- >>> runReader (runExitcode (ask :: Exitcode () (Control.Monad.Reader.Reader Int) Int)) 42+-- Right 42+-- >>> runReader (runExitcode (local (+1) ask :: Exitcode () (Control.Monad.Reader.Reader Int) Int)) 42+-- Right 43+instance (MonadReader r f) => MonadReader r (Exitcode e f) where+  {-# INLINE ask #-}+  ask = Exitcode (asks Right)+  {-# INLINE local #-}+  local f (Exitcode m) = Exitcode (local f m)++-- |+--+-- >>> import Control.Monad.Writer (runWriter)+-- >>> runWriter (runExitcode (tell "hello" :: Exitcode () (Control.Monad.Writer.Lazy.Writer String) ()))+-- (Right (),"hello")+instance (MonadWriter w f) => MonadWriter w (Exitcode e f) where+  {-# INLINE writer #-}+  writer t = Exitcode . fmap pure $ writer t+  {-# INLINE listen #-}+  listen (Exitcode m) = Exitcode ((\(e, w) -> (,w) <$> e) <$> listen m)+  {-# INLINE tell #-}+  tell = Exitcode . fmap Right . tell+  {-# INLINE pass #-}+  pass e =+    do+      ((a, f), w) <- listen e+      tell (f w)+      pure a++-- |+--+-- >>> import Control.Monad.State (runState)+-- >>> runState (runExitcode (get :: Exitcode () (Control.Monad.State.Lazy.State Int) Int)) 7+-- (Right 7,7)+-- >>> runState (runExitcode (put 99 :: Exitcode () (Control.Monad.State.Lazy.State Int) ())) 7+-- (Right (),99)+instance (MonadState s f) => MonadState s (Exitcode e f) where+  {-# INLINE get #-}+  get = Exitcode (fmap Right get)+  {-# INLINE put #-}+  put = Exitcode . fmap Right . put++-- | @throwError@ and @catchError@ operate on the error channel of the base+-- functor @f@, not on the exit code failure.+--+-- >>> import Control.Monad.Except (runExcept)+-- >>> runExcept (runExitcode (throwError "oops" :: Exitcode () (Control.Monad.Except.Except String) Int))+-- Left "oops"+instance (MonadError e f) => MonadError e (Exitcode e' f) where+  {-# INLINE throwError #-}+  throwError = Exitcode . fmap Right . throwError+  {-# INLINE catchError #-}+  catchError (Exitcode f) h = Exitcode (catchError f (runExitcode . h))++instance (MonadRWS r w s f) => MonadRWS r w s (Exitcode e f)++-- |+--+-- >>> import Control.Monad.Cont (runCont)+-- >>> runCont (runExitcode (callCC (\k -> k 42) :: Exitcode () (Control.Monad.Cont.Cont (Either ((), NotZero) Int)) Int)) id+-- Right 42+instance (MonadCont f) => MonadCont (Exitcode e f) where+  callCC f =+    Exitcode (callCC (\c -> runExitcode (f (Exitcode . c . Right))))++-- |+--+-- >>> import Control.Monad.Trans.Class (lift)+-- >>> runExitcode (lift (Identity 42) :: Exitcode' () Int)+-- Identity (Right 42)+instance MonadTrans (Exitcode e) where+  {-# INLINE lift #-}+  lift = Exitcode . fmap Right++-- |+--+-- >>> import Data.Functor.Bind.Trans (liftB)+-- >>> runExitcode (liftB (Identity 42) :: Exitcode' () Int)+-- Identity (Right 42)+instance BindTrans (Exitcode e) where+  {-# INLINE liftB #-}+  liftB = Exitcode . fmap Right++-- * ExitcodeBifunctor++-- | @ExitcodeBifunctor@ reorders the type parameters of @Exitcode@ so that+-- @e@ and @a@ are last, enabling @Bifunctor@, @Bifoldable@, and @Bitraversable@+-- instances.+newtype ExitcodeBifunctor f e a = ExitcodeBifunctor (Exitcode e f a)+  deriving stock (Generic)++-- | @ExitcodeBifunctor@ specialised to @Identity@.+type ExitcodeBifunctor' e a = ExitcodeBifunctor Identity e a++-- * ExitcodeBifunctor Instances++-- |+--+-- >>> bimap (+1) (+10) (ExitcodeBifunctor (mkExitFailure1' 5) :: ExitcodeBifunctor' Int Int)+-- ExitcodeBifunctor (Exitcode (Identity (Left (6,NotZero True (Positive 1)))))+-- >>> bimap (+1) (+10) (ExitcodeBifunctor (mkExitSuccess' 5) :: ExitcodeBifunctor' Int Int)+-- ExitcodeBifunctor (Exitcode (Identity (Right 15)))+instance (Functor f) => Bifunctor (ExitcodeBifunctor f) where+  {-# INLINE bimap #-}+  bimap f g (ExitcodeBifunctor x) = ExitcodeBifunctor (bimapExitcode f g x)++-- |+--+-- >>> bifoldMap show show (ExitcodeBifunctor (mkExitFailure1' 'x') :: ExitcodeBifunctor' Char Int)+-- "'x'"+-- >>> bifoldMap show show (ExitcodeBifunctor (mkExitSuccess' 42) :: ExitcodeBifunctor' Char Int)+-- "42"+instance (Foldable f) => Bifoldable (ExitcodeBifunctor f) where+  {-# INLINE bifoldMap #-}+  bifoldMap f g (ExitcodeBifunctor (Exitcode x)) =+    foldMap (either (\(e, _) -> f e) g) x++-- |+--+-- >>> bitraverse (Just . (+1)) (Just . (+10)) (ExitcodeBifunctor (mkExitFailure1' 5) :: ExitcodeBifunctor' Int Int)+-- Just (ExitcodeBifunctor (Exitcode (Identity (Left (6,NotZero True (Positive 1))))))+-- >>> bitraverse (Just . (+1)) (Just . (+10)) (ExitcodeBifunctor (mkExitSuccess' 5) :: ExitcodeBifunctor' Int Int)+-- Just (ExitcodeBifunctor (Exitcode (Identity (Right 15))))+instance (Traversable f) => Bitraversable (ExitcodeBifunctor f) where+  {-# INLINE bitraverse #-}+  bitraverse f g (ExitcodeBifunctor (Exitcode x)) =+    ExitcodeBifunctor . Exitcode <$> traverse (either (\(e, n) -> fmap (\e' -> Left (e', n)) (f e)) (fmap Right . g)) x++-- |+--+-- >>> fmap (+1) (ExitcodeBifunctor (mkExitSuccess' 3) :: ExitcodeBifunctor' () Int)+-- ExitcodeBifunctor (Exitcode (Identity (Right 4)))+instance (Functor f) => Functor (ExitcodeBifunctor f e) where+  {-# INLINE fmap #-}+  fmap f (ExitcodeBifunctor x) = ExitcodeBifunctor (fmap f x)++-- |+--+-- >>> foldMap show (ExitcodeBifunctor (mkExitSuccess' 42) :: ExitcodeBifunctor' () Int)+-- "42"+instance (Foldable f) => Foldable (ExitcodeBifunctor f e) where+  {-# INLINE foldMap #-}+  foldMap f (ExitcodeBifunctor x) = foldMap f x++-- |+--+-- >>> traverse Just (ExitcodeBifunctor (mkExitSuccess' 42) :: ExitcodeBifunctor' () Int)+-- Just (ExitcodeBifunctor (Exitcode (Identity (Right 42))))+instance (Traversable f) => Traversable (ExitcodeBifunctor f e) where+  {-# INLINE traverse #-}+  traverse f (ExitcodeBifunctor x) = ExitcodeBifunctor <$> traverse f x++instance (FunctorWithIndex i f) => FunctorWithIndex i (ExitcodeBifunctor f e) where+  {-# INLINE imap #-}+  imap f (ExitcodeBifunctor x) = ExitcodeBifunctor (imap f x)++instance (FoldableWithIndex i f) => FoldableWithIndex i (ExitcodeBifunctor f e) where+  {-# INLINE ifoldMap #-}+  ifoldMap f (ExitcodeBifunctor x) = ifoldMap f x++instance (TraversableWithIndex i f) => TraversableWithIndex i (ExitcodeBifunctor f e) where+  {-# INLINE itraverse #-}+  itraverse f (ExitcodeBifunctor x) = ExitcodeBifunctor <$> itraverse f x++instance (Monad f) => Apply (ExitcodeBifunctor f e) where+  {-# INLINE (<.>) #-}+  ExitcodeBifunctor f <.> ExitcodeBifunctor a = ExitcodeBifunctor (f <.> a)++-- |+--+-- >>> pure 42 :: ExitcodeBifunctor' () Int+-- ExitcodeBifunctor (Exitcode (Identity (Right 42)))+instance (Monad f) => Applicative (ExitcodeBifunctor f e) where+  {-# INLINE pure #-}+  pure = ExitcodeBifunctor . pure+  {-# INLINE (<*>) #-}+  ExitcodeBifunctor f <*> ExitcodeBifunctor a = ExitcodeBifunctor (f <*> a)++instance (Monad f) => Bind (ExitcodeBifunctor f e) where+  {-# INLINE (>>-) #-}+  (>>-) = (>>=)++instance (Monad f) => Monad (ExitcodeBifunctor f e) where+  {-# INLINE (>>=) #-}+  ExitcodeBifunctor x >>= f = ExitcodeBifunctor (x >>= (\a -> let ExitcodeBifunctor y = f a in y))++instance (MonadFix f) => MonadFix (ExitcodeBifunctor f e) where+  {-# INLINE mfix #-}+  mfix f = ExitcodeBifunctor (mfix (\a -> let ExitcodeBifunctor y = f a in y))++-- |+--+-- >>> (ExitcodeBifunctor (mkExitFailure1' ()) :: ExitcodeBifunctor' () Int) <!> ExitcodeBifunctor (mkExitSuccess' 42)+-- ExitcodeBifunctor (Exitcode (Identity (Right 42)))+instance (Monad f) => Alt (ExitcodeBifunctor f e) where+  {-# INLINE (<!>) #-}+  ExitcodeBifunctor a <!> ExitcodeBifunctor b = ExitcodeBifunctor (a <!> b)++instance (Semigroup a, Monad f) => Semigroup (ExitcodeBifunctor f e a) where+  {-# INLINE (<>) #-}+  ExitcodeBifunctor a <> ExitcodeBifunctor b = ExitcodeBifunctor (a <> b)++instance (Monoid a, Monad f) => Monoid (ExitcodeBifunctor f e a) where+  {-# INLINE mempty #-}+  mempty = ExitcodeBifunctor mempty++instance (Extend f) => Extend (ExitcodeBifunctor f e) where+  {-# INLINE duplicated #-}+  duplicated (ExitcodeBifunctor x) = ExitcodeBifunctor (fmap ExitcodeBifunctor (duplicated x))++instance (Eq (f (Either (e, NotZero) a))) => Eq (ExitcodeBifunctor f e a) where+  {-# INLINE (==) #-}+  ExitcodeBifunctor (Exitcode a) == ExitcodeBifunctor (Exitcode b) = a == b++instance (Eq1 f, Eq e) => Eq1 (ExitcodeBifunctor f e) where+  {-# INLINE liftEq #-}+  liftEq f (ExitcodeBifunctor (Exitcode a)) (ExitcodeBifunctor (Exitcode b)) =+    liftEq (liftEq f) a b++instance (Ord (f (Either (e, NotZero) a))) => Ord (ExitcodeBifunctor f e a) where+  {-# INLINE compare #-}+  ExitcodeBifunctor (Exitcode a) `compare` ExitcodeBifunctor (Exitcode b) = compare a b++instance (Ord1 f, Ord e) => Ord1 (ExitcodeBifunctor f e) where+  {-# INLINE liftCompare #-}+  liftCompare f (ExitcodeBifunctor (Exitcode a)) (ExitcodeBifunctor (Exitcode b)) =+    liftCompare (liftCompare f) a b++-- |+--+-- >>> show (ExitcodeBifunctor (mkExitSuccess' "abc") :: ExitcodeBifunctor' () String)+-- "ExitcodeBifunctor (Exitcode (Identity (Right \"abc\")))"+-- >>> show (ExitcodeBifunctor (mkExitFailure1' 'x') :: ExitcodeBifunctor' Char ())+-- "ExitcodeBifunctor (Exitcode (Identity (Left ('x',NotZero True (Positive 1)))))"+instance (Show (f (Either (e, NotZero) a))) => Show (ExitcodeBifunctor f e a) where+  {-# INLINE showsPrec #-}+  showsPrec d (ExitcodeBifunctor (Exitcode m)) =+    showParen (d > 10) $+      showString "ExitcodeBifunctor (Exitcode " . showsPrec 11 m . showString ")"++instance (Show1 f, Show e) => Show1 (ExitcodeBifunctor f e) where+  {-# INLINE liftShowsPrec #-}+  liftShowsPrec sp sl d (ExitcodeBifunctor (Exitcode fa)) =+    showParen (d > 10) $+      showString "ExitcodeBifunctor (Exitcode "+        . liftShowsPrec (liftShowsPrec sp sl) (liftShowList sp sl) 11 fa+        . showString ")"++instance (NFData1 f, NFData e, NFData a) => NFData (ExitcodeBifunctor f e a) where+  {-# INLINE rnf #-}+  rnf = liftRnf rnf++instance (NFData1 f, NFData e) => NFData1 (ExitcodeBifunctor f e) where+  {-# INLINE liftRnf #-}+  liftRnf r (ExitcodeBifunctor (Exitcode x)) = liftRnf rnfEither x+    where+      rnfEither (Right a) = r a+      rnfEither (Left (e, n)) = rnf e `seq` rnf (review _NotZero n :: Int)++instance (MonadIO f) => MonadIO (ExitcodeBifunctor f e) where+  {-# INLINE liftIO #-}+  liftIO = ExitcodeBifunctor . liftIO++instance (MonadReader r f) => MonadReader r (ExitcodeBifunctor f e) where+  {-# INLINE ask #-}+  ask = ExitcodeBifunctor ask+  {-# INLINE local #-}+  local f (ExitcodeBifunctor x) = ExitcodeBifunctor (local f x)++instance (MonadWriter w f) => MonadWriter w (ExitcodeBifunctor f e) where+  {-# INLINE writer #-}+  writer t = ExitcodeBifunctor (writer t)+  {-# INLINE listen #-}+  listen (ExitcodeBifunctor x) = ExitcodeBifunctor (listen x)+  {-# INLINE tell #-}+  tell = ExitcodeBifunctor . tell+  {-# INLINE pass #-}+  pass (ExitcodeBifunctor x) = ExitcodeBifunctor (pass x)++instance (MonadState s f) => MonadState s (ExitcodeBifunctor f e) where+  {-# INLINE get #-}+  get = ExitcodeBifunctor get+  {-# INLINE put #-}+  put = ExitcodeBifunctor . put++instance (MonadError e f) => MonadError e (ExitcodeBifunctor f e') where+  {-# INLINE throwError #-}+  throwError = ExitcodeBifunctor . throwError+  {-# INLINE catchError #-}+  catchError (ExitcodeBifunctor x) h = ExitcodeBifunctor (catchError x (\e -> let ExitcodeBifunctor y = h e in y))++instance (MonadRWS r w s f) => MonadRWS r w s (ExitcodeBifunctor f e)++instance (MonadCont f) => MonadCont (ExitcodeBifunctor f e) where+  callCC f = ExitcodeBifunctor (callCC (\c -> let ExitcodeBifunctor x = f (ExitcodeBifunctor . c) in x))+
+ src/Control/Exitcode/Optics.hs view
@@ -0,0 +1,219 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# OPTIONS_GHC -Wall #-}++module Control.Exitcode.Optics+  ( GetExitcode (..),+    HasExitcode (..),+    ReviewExitcode (..),+    AsExitcode (..),+    GetExitcodeBifunctor (..),+    HasExitcodeBifunctor (..),+    ReviewExitcodeBifunctor (..),+    AsExitcodeBifunctor (..),+  )+where++import Control.Category (id, (.))+import Control.Exitcode.Exitcode (Exitcode, ExitcodeBifunctor (ExitcodeBifunctor))+import Control.Lens (Getter, Lens', Prism', Review, lens, prism', unto)+import Data.Maybe (Maybe (Just))++-- $setup+-- >>> import Prelude+-- >>> import Control.Lens+-- >>> import Control.Exitcode++-- * Exitcode optics++-- | Type class for values that can be viewed as an @Exitcode@.+--+-- >>> view getExitcode (mkExitSuccess' "abc" :: Exitcode' () String) :: Exitcode' () String+-- Exitcode (Identity (Right "abc"))+class GetExitcode s e f a | s -> e f a where+  getExitcode :: Getter s (Exitcode e f a)++-- |+--+-- >>> view getExitcode (mkExitSuccess' "abc" :: Exitcode' () String)+-- Exitcode (Identity (Right "abc"))+instance GetExitcode (Exitcode e f a) e f a where+  getExitcode = id+  {-# INLINE getExitcode #-}++-- |+--+-- >>> view getExitcode (ExitcodeBifunctor (mkExitSuccess' "abc") :: ExitcodeBifunctor' () String)+-- Exitcode (Identity (Right "abc"))+instance GetExitcode (ExitcodeBifunctor f e a) e f a where+  getExitcode = lens (\(ExitcodeBifunctor x) -> x) (\_ -> ExitcodeBifunctor)+  {-# INLINE getExitcode #-}++-- | Type class for values with a lens into an @Exitcode@.+--+-- >>> view exitcode (mkExitSuccess' "abc" :: Exitcode' () String)+-- Exitcode (Identity (Right "abc"))+class (GetExitcode s e f a) => HasExitcode s e f a | s -> e f a where+  exitcode :: Lens' s (Exitcode e f a)++-- |+--+-- >>> view exitcode (mkExitSuccess' "abc" :: Exitcode' () String)+-- Exitcode (Identity (Right "abc"))+instance HasExitcode (Exitcode e f a) e f a where+  exitcode = id+  {-# INLINE exitcode #-}++-- |+--+-- >>> view exitcode (ExitcodeBifunctor (mkExitSuccess' "abc") :: ExitcodeBifunctor' () String)+-- Exitcode (Identity (Right "abc"))+-- >>> set exitcode (mkExitFailure1' ()) (ExitcodeBifunctor (mkExitSuccess' "abc") :: ExitcodeBifunctor' () String)+-- ExitcodeBifunctor (Exitcode (Identity (Left ((),NotZero True (Positive 1)))))+instance HasExitcode (ExitcodeBifunctor f e a) e f a where+  exitcode = lens (\(ExitcodeBifunctor x) -> x) (\_ x -> ExitcodeBifunctor x)+  {-# INLINE exitcode #-}++-- | Type class for values that can be constructed from an @Exitcode@.+--+-- >>> review reviewExitcode (mkExitSuccess' "abc" :: Exitcode' () String) :: Exitcode' () String+-- Exitcode (Identity (Right "abc"))+class ReviewExitcode t e f a | t -> e f a where+  reviewExitcode :: Review t (Exitcode e f a)++-- |+--+-- >>> review reviewExitcode (mkExitSuccess' "abc" :: Exitcode' () String) :: Exitcode' () String+-- Exitcode (Identity (Right "abc"))+instance ReviewExitcode (Exitcode e f a) e f a where+  reviewExitcode = unto id+  {-# INLINE reviewExitcode #-}++-- |+--+-- >>> review reviewExitcode (mkExitSuccess' "abc" :: Exitcode' () String) :: ExitcodeBifunctor' () String+-- ExitcodeBifunctor (Exitcode (Identity (Right "abc")))+instance ReviewExitcode (ExitcodeBifunctor f e a) e f a where+  reviewExitcode = unto ExitcodeBifunctor+  {-# INLINE reviewExitcode #-}++-- | Type class for values with a prism into an @Exitcode@.+--+-- >>> preview _Exitcode (mkExitSuccess' "abc" :: Exitcode' () String) :: Maybe (Exitcode' () String)+-- Just (Exitcode (Identity (Right "abc")))+class (ReviewExitcode t e f a) => AsExitcode t e f a | t -> e f a where+  _Exitcode :: Prism' t (Exitcode e f a)++-- |+--+-- >>> preview _Exitcode (mkExitSuccess' "abc" :: Exitcode' () String) :: Maybe (Exitcode' () String)+-- Just (Exitcode (Identity (Right "abc")))+instance AsExitcode (Exitcode e f a) e f a where+  _Exitcode = id+  {-# INLINE _Exitcode #-}++-- |+--+-- >>> preview _Exitcode (ExitcodeBifunctor (mkExitSuccess' "abc") :: ExitcodeBifunctor' () String) :: Maybe (Exitcode' () String)+-- Just (Exitcode (Identity (Right "abc")))+instance AsExitcode (ExitcodeBifunctor f e a) e f a where+  _Exitcode = prism' ExitcodeBifunctor (\(ExitcodeBifunctor x) -> Just x)+  {-# INLINE _Exitcode #-}++-- * ExitcodeBifunctor optics++-- | Type class for values that can be viewed as an @ExitcodeBifunctor@.+--+-- >>> view getExitcodeBifunctor (ExitcodeBifunctor (mkExitSuccess' "abc") :: ExitcodeBifunctor' () String)+-- ExitcodeBifunctor (Exitcode (Identity (Right "abc")))+class GetExitcodeBifunctor s f e a | s -> f e a where+  getExitcodeBifunctor :: Getter s (ExitcodeBifunctor f e a)++-- |+--+-- >>> view getExitcodeBifunctor (ExitcodeBifunctor (mkExitSuccess' "abc") :: ExitcodeBifunctor' () String)+-- ExitcodeBifunctor (Exitcode (Identity (Right "abc")))+instance GetExitcodeBifunctor (ExitcodeBifunctor f e a) f e a where+  getExitcodeBifunctor = id+  {-# INLINE getExitcodeBifunctor #-}++-- |+--+-- >>> view getExitcodeBifunctor (mkExitSuccess' "abc" :: Exitcode' () String)+-- ExitcodeBifunctor (Exitcode (Identity (Right "abc")))+instance GetExitcodeBifunctor (Exitcode e f a) f e a where+  getExitcodeBifunctor = lens ExitcodeBifunctor (\_ (ExitcodeBifunctor x) -> x)+  {-# INLINE getExitcodeBifunctor #-}++-- | Type class for values with a lens into an @ExitcodeBifunctor@.+--+-- >>> view exitcodeBifunctor (ExitcodeBifunctor (mkExitSuccess' "abc") :: ExitcodeBifunctor' () String)+-- ExitcodeBifunctor (Exitcode (Identity (Right "abc")))+class (GetExitcodeBifunctor s f e a) => HasExitcodeBifunctor s f e a | s -> f e a where+  exitcodeBifunctor :: Lens' s (ExitcodeBifunctor f e a)++-- |+--+-- >>> view exitcodeBifunctor (ExitcodeBifunctor (mkExitSuccess' "abc") :: ExitcodeBifunctor' () String)+-- ExitcodeBifunctor (Exitcode (Identity (Right "abc")))+instance HasExitcodeBifunctor (ExitcodeBifunctor f e a) f e a where+  exitcodeBifunctor = id+  {-# INLINE exitcodeBifunctor #-}++-- |+--+-- >>> view exitcodeBifunctor (mkExitSuccess' "abc" :: Exitcode' () String)+-- ExitcodeBifunctor (Exitcode (Identity (Right "abc")))+-- >>> set exitcodeBifunctor (ExitcodeBifunctor (mkExitFailure1' ())) (mkExitSuccess' "abc" :: Exitcode' () String)+-- Exitcode (Identity (Left ((),NotZero True (Positive 1))))+instance HasExitcodeBifunctor (Exitcode e f a) f e a where+  exitcodeBifunctor = lens ExitcodeBifunctor (\_ (ExitcodeBifunctor x) -> x)+  {-# INLINE exitcodeBifunctor #-}++-- | Type class for values that can be constructed from an @ExitcodeBifunctor@.+--+-- >>> review reviewExitcodeBifunctor (ExitcodeBifunctor (mkExitSuccess' "abc") :: ExitcodeBifunctor' () String) :: ExitcodeBifunctor' () String+-- ExitcodeBifunctor (Exitcode (Identity (Right "abc")))+class ReviewExitcodeBifunctor t f e a | t -> f e a where+  reviewExitcodeBifunctor :: Review t (ExitcodeBifunctor f e a)++-- |+--+-- >>> review reviewExitcodeBifunctor (ExitcodeBifunctor (mkExitSuccess' "abc") :: ExitcodeBifunctor' () String) :: ExitcodeBifunctor' () String+-- ExitcodeBifunctor (Exitcode (Identity (Right "abc")))+instance ReviewExitcodeBifunctor (ExitcodeBifunctor f e a) f e a where+  reviewExitcodeBifunctor = unto id+  {-# INLINE reviewExitcodeBifunctor #-}++-- |+--+-- >>> review reviewExitcodeBifunctor (ExitcodeBifunctor (mkExitSuccess' "abc") :: ExitcodeBifunctor' () String) :: Exitcode' () String+-- Exitcode (Identity (Right "abc"))+instance ReviewExitcodeBifunctor (Exitcode e f a) f e a where+  reviewExitcodeBifunctor = unto (\(ExitcodeBifunctor x) -> x)+  {-# INLINE reviewExitcodeBifunctor #-}++-- | Type class for values with a prism into an @ExitcodeBifunctor@.+--+-- >>> preview _ExitcodeBifunctor (ExitcodeBifunctor (mkExitSuccess' "abc") :: ExitcodeBifunctor' () String)+-- Just (ExitcodeBifunctor (Exitcode (Identity (Right "abc"))))+class (ReviewExitcodeBifunctor t f e a) => AsExitcodeBifunctor t f e a | t -> f e a where+  _ExitcodeBifunctor :: Prism' t (ExitcodeBifunctor f e a)++-- |+--+-- >>> preview _ExitcodeBifunctor (ExitcodeBifunctor (mkExitSuccess' "abc") :: ExitcodeBifunctor' () String)+-- Just (ExitcodeBifunctor (Exitcode (Identity (Right "abc"))))+instance AsExitcodeBifunctor (ExitcodeBifunctor f e a) f e a where+  _ExitcodeBifunctor = id+  {-# INLINE _ExitcodeBifunctor #-}++-- |+--+-- >>> preview _ExitcodeBifunctor (mkExitSuccess' "abc" :: Exitcode' () String)+-- Just (ExitcodeBifunctor (Exitcode (Identity (Right "abc"))))+instance AsExitcodeBifunctor (Exitcode e f a) f e a where+  _ExitcodeBifunctor = prism' (\(ExitcodeBifunctor x) -> x) (Just . ExitcodeBifunctor)+  {-# INLINE _ExitcodeBifunctor #-}
src/Control/Process.hs view
@@ -1,9 +1,10 @@-{-# OPTIONS_GHC -Wall #-} {-# LANGUAGE NoImplicitPrelude #-}+{-# OPTIONS_GHC -Wall #-} -module Control.Process(-  module P-) where+module Control.Process+  ( module P,+  )+where  import Control.Process.CmdSpec as P import Control.Process.CreateProcess as P
src/Control/Process/CmdSpec.hs view
@@ -1,97 +1,195 @@-{-# OPTIONS_GHC -Wall #-}-{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE LambdaCase #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# OPTIONS_GHC -Wall #-} -module Control.Process.CmdSpec(-  AsCmdSpec(..)-, HasCmdSpec(..)-) where+module Control.Process.CmdSpec+  ( CmdSpec (..),+    GetCmdSpec (..),+    HasCmdSpec (..),+    ReviewCmdSpec (..),+    AsCmdSpec (..),+  )+where -import Control.Category ( Category(id, (.)) )+import Control.Category (id, (.)) import Control.Lens-    ( Traversable(traverse),-      prism',-      Field1(_1),-      Field2(_2),-      Lens',-      Prism',-      Traversal' )-import Data.Maybe ( Maybe(Nothing, Just) )-import Data.Functor ( Functor(fmap) )-import Data.String ( String )-import Data.Tuple ( uncurry )-import System.FilePath ( FilePath )-import System.Process ( CreateProcess(..), CmdSpec(..) )+  ( Field1 (_1),+    Field2 (_2),+    Getter,+    Lens',+    Prism',+    Review,+    Traversable (traverse),+    Traversal',+    prism',+    to,+    unto,+  )+import Data.Functor (Functor (fmap))+import Data.Maybe (Maybe (Just, Nothing))+import Data.String (String)+import Data.Tuple (uncurry)+import System.FilePath (FilePath)+import System.Process (CmdSpec (..), CreateProcess)+import qualified System.Process as Process (CreateProcess (..)) -class AsCmdSpec a where+-- $setup+-- >>> import Prelude+-- >>> import Control.Lens++-- | Type class for values that can be viewed as a @CmdSpec@.+--+-- >>> view getCmdSpec (ShellCommand "ls -la")+-- ShellCommand "ls -la"+class GetCmdSpec a where+  getCmdSpec ::+    Getter a CmdSpec++-- |+--+-- >>> view getCmdSpec (ShellCommand "ls -la")+-- ShellCommand "ls -la"+instance GetCmdSpec CmdSpec where+  getCmdSpec = id+  {-# INLINE getCmdSpec #-}++-- |+--+-- >>> import System.Process (proc)+-- >>> view getCmdSpec (proc "echo" ["hello"])+-- RawCommand "echo" ["hello"]+instance GetCmdSpec CreateProcess where+  getCmdSpec = to Process.cmdspec+  {-# INLINE getCmdSpec #-}++-- | Type class for values with a lens into a @CmdSpec@.+--+-- >>> view cmdSpec (ShellCommand "ls -la")+-- ShellCommand "ls -la"+class (GetCmdSpec a) => HasCmdSpec a where+  cmdSpec ::+    Lens' a CmdSpec+  {-# INLINE shellCommand #-}+  shellCommand ::+    Traversal' a String+  shellCommand =+    cmdSpec . _ShellCommand+  {-# INLINE rawCommand #-}+  rawCommand ::+    Traversal' a (FilePath, [String])+  rawCommand =+    cmdSpec . _RawCommand+  {-# INLINE rawCommandExe #-}+  rawCommandExe ::+    Traversal' a FilePath+  rawCommandExe =+    rawCommand . _1+  {-# INLINE rawCommandArgumentList #-}+  rawCommandArgumentList ::+    Traversal' a [String]+  rawCommandArgumentList =+    rawCommand . _2+  {-# INLINE rawCommandArguments #-}+  rawCommandArguments ::+    Traversal' a String+  rawCommandArguments =+    rawCommandArgumentList . traverse++-- |+--+-- >>> view cmdSpec (ShellCommand "ls")+-- ShellCommand "ls"+-- >>> set cmdSpec (RawCommand "echo" ["hi"]) (ShellCommand "ls")+-- RawCommand "echo" ["hi"]+instance HasCmdSpec CmdSpec where+  cmdSpec =+    id++-- |+--+-- >>> import System.Process (proc)+-- >>> view cmdSpec (proc "echo" ["hello"])+-- RawCommand "echo" ["hello"]+instance HasCmdSpec CreateProcess where+  cmdSpec f p =+    fmap (\x -> p {Process.cmdspec = x}) (f (Process.cmdspec p))++-- | Type class for values that can be constructed from a @CmdSpec@.+--+-- >>> review reviewCmdSpec (ShellCommand "ls") :: CmdSpec+-- ShellCommand "ls"+class ReviewCmdSpec a where+  reviewCmdSpec ::+    Review a CmdSpec++-- |+--+-- >>> review reviewCmdSpec (ShellCommand "ls") :: CmdSpec+-- ShellCommand "ls"+instance ReviewCmdSpec CmdSpec where+  reviewCmdSpec = unto id+  {-# INLINE reviewCmdSpec #-}++-- | Type class for values with a prism into a @CmdSpec@.+--+-- >>> preview _CmdSpec (ShellCommand "ls -la")+-- Just (ShellCommand "ls -la")+class (ReviewCmdSpec a) => AsCmdSpec a where   _CmdSpec ::     Prism' a CmdSpec+  {-# INLINE _ShellCommand #-}   _ShellCommand ::     Prism' a String   _ShellCommand =     _CmdSpec . _ShellCommand+  {-# INLINE _RawCommand #-}   _RawCommand ::     Prism' a (FilePath, [String])   _RawCommand =     _CmdSpec . _RawCommand+  {-# INLINE _RawCommandExe #-}   _RawCommandExe ::     Traversal' a FilePath   _RawCommandExe =     _RawCommand . _1+  {-# INLINE _RawCommandArgumentList #-}   _RawCommandArgumentList ::     Traversal' a [String]   _RawCommandArgumentList =     _RawCommand . _2+  {-# INLINE _RawCommandArguments #-}   _RawCommandArguments ::     Traversal' a String   _RawCommandArguments =     _RawCommandArgumentList . traverse +-- |+--+-- >>> preview _ShellCommand (ShellCommand "ls -la")+-- Just "ls -la"+-- >>> preview _ShellCommand (RawCommand "ls" ["-la"])+-- Nothing+-- >>> preview _RawCommand (RawCommand "ls" ["-la"])+-- Just ("ls",["-la"])+-- >>> preview _RawCommand (ShellCommand "ls -la")+-- Nothing+-- >>> review _ShellCommand "echo hello" :: CmdSpec+-- ShellCommand "echo hello"+-- >>> review _RawCommand ("/bin/ls", ["-la"]) :: CmdSpec+-- RawCommand "/bin/ls" ["-la"] instance AsCmdSpec CmdSpec where   _CmdSpec = id   _ShellCommand =     prism'       ShellCommand-      (\case-        ShellCommand a -> Just a-        _ -> Nothing+      ( \case+          ShellCommand a -> Just a+          _ -> Nothing       )   _RawCommand =     prism'       (uncurry RawCommand)-      (\case-        RawCommand a b -> Just (a, b)-        _ -> Nothing+      ( \case+          RawCommand a b -> Just (a, b)+          _ -> Nothing       )--class HasCmdSpec a where-  cmdSpec ::-    Lens' a CmdSpec-  shellCommand ::-    Traversal' a String-  shellCommand =-    cmdSpec . _ShellCommand-  rawCommand ::-    Traversal' a (FilePath, [String])-  rawCommand =-    cmdSpec . _RawCommand-  rawCommandExe ::-    Traversal' a FilePath-  rawCommandExe =-    rawCommand . _1-  rawCommandArgumentList ::-    Traversal' a [String]-  rawCommandArgumentList =-    rawCommand . _2-  rawCommandArguments ::-    Traversal' a String-  rawCommandArguments =-    rawCommandArgumentList . traverse--instance HasCmdSpec CmdSpec where-  cmdSpec =-    id--instance HasCmdSpec CreateProcess where-  cmdSpec f (CreateProcess csc cw en sti sto ste clf crg dct dcl cnc nss chg chu upj) =-    fmap (\csc' -> CreateProcess csc' cw en sti sto ste clf crg dct dcl cnc nss chg chu upj) (f csc)
src/Control/Process/CreateProcess.hs view
@@ -1,37 +1,71 @@-{-# OPTIONS_GHC -Wall #-} {-# LANGUAGE NoImplicitPrelude #-}+{-# OPTIONS_GHC -Wall #-} -module Control.Process.CreateProcess(-  HasCreateProcess(..)-, AsCreateProcess(..)-, streams-, streams1-) where+module Control.Process.CreateProcess+  ( CreateProcess,+    GetCreateProcess (..),+    HasCreateProcess (..),+    ReviewCreateProcess (..),+    AsCreateProcess (..),+    streams,+    streams1,+  )+where -import Control.Applicative ( Applicative((<*>)) )-import Control.Category ( Category(id, (.)) )+import Control.Applicative (Applicative ((<*>)))+import Control.Category (id, (.)) import Control.Lens-    ( Traversable(traverse),-      _Just,-      only,-      Field1(_1),-      Field2(_2),-      Lens',-      Prism',-      Traversal',-      Traversal1' )-import Control.Process.UserID ( HasUserID(userIDWord32) )-import Data.Bool ( Bool(True) )-import Data.Functor ( Functor(fmap), (<$>) )-import Data.Functor.Apply ( Apply((<.>)) )-import Data.Maybe ( Maybe(..) )-import Data.String ( String )-import Data.Word ( Word32 )-import System.FilePath ( FilePath )-import System.Process(StdStream(..), CreateProcess(CreateProcess))-import System.Process.Internals(GroupID, UserID)+  ( Field1 (_1),+    Field2 (_2),+    Getter,+    Lens',+    Prism',+    Review,+    Traversable (traverse),+    Traversal',+    Traversal1',+    only,+    unto,+    _Just,+  )+import Control.Process.UserID (HasUserID (userIDWord32))+import Data.Bool (Bool (True))+import Data.Functor (Functor (fmap), (<$>))+import Data.Functor.Apply (Apply ((<.>)))+import Data.Maybe (Maybe (..))+import Data.String (String)+import Data.Word (Word32)+import System.FilePath (FilePath)+import System.Process (CreateProcess, StdStream (..))+import qualified System.Process as Process (CreateProcess (..))+import System.Process.Internals (GroupID, UserID) -class HasCreateProcess a where+-- $setup+-- >>> import Prelude+-- >>> import Control.Lens+-- >>> import System.Process (proc, shell)++-- | Type class for values that can be viewed as a @CreateProcess@.+--+-- >>> view getCreateProcess (proc "echo" ["hello"]) == proc "echo" ["hello"]+-- True+class GetCreateProcess a where+  getCreateProcess ::+    Getter a CreateProcess++-- |+--+-- >>> view getCreateProcess (proc "echo" ["hello"]) == proc "echo" ["hello"]+-- True+instance GetCreateProcess CreateProcess where+  getCreateProcess = id+  {-# INLINE getCreateProcess #-}++-- | Type class for values with a lens into a @CreateProcess@.+--+-- >>> view close_fds (proc "echo" ["hello"])+-- False+class (GetCreateProcess a) => HasCreateProcess a where   create_process ::     Lens' a CreateProcess   {-# INLINE child_group #-}@@ -105,113 +139,176 @@   use_process_jobs =     create_process . use_process_jobs +  {-# INLINE cwd' #-}   cwd' ::     Traversal' a FilePath   cwd' =     cwd . _Just+  {-# INLINE envList #-}   envList ::     Traversal' a [(String, String)]   envList =     env . _Just+  {-# INLINE envElement #-}   envElement ::     Traversal' a (String, String)   envElement =     envList . traverse+  {-# INLINE envElementKey #-}   envElementKey ::     Traversal' a String   envElementKey =     envElement . _1+  {-# INLINE envElementValue #-}   envElementValue ::     Traversal' a String   envElementValue =     envElement . _2+  {-# INLINE close_fds' #-}   close_fds' ::     Traversal' a ()   close_fds' =     close_fds . only True+  {-# INLINE create_group' #-}   create_group' ::     Traversal' a ()   create_group' =     create_group . only True+  {-# INLINE delegate_ctlc' #-}   delegate_ctlc' ::     Traversal' a ()   delegate_ctlc' =     delegate_ctlc . only True+  {-# INLINE detach_console' #-}   detach_console' ::     Traversal' a ()   detach_console' =     detach_console . only True+  {-# INLINE create_new_console' #-}   create_new_console' ::     Traversal' a ()   create_new_console' =     create_new_console . only True+  {-# INLINE new_session' #-}   new_session' ::     Traversal' a ()   new_session' =     new_session . only True+  {-# INLINE child_group' #-}   child_group' ::     Traversal' a GroupID   child_group' =     child_group . _Just+  {-# INLINE child_user' #-}   child_user' ::     Traversal' a UserID   child_user' =     child_user . _Just+  {-# INLINE child_user'' #-}   child_user'' ::     Traversal' a Word32   child_user'' =     child_user' . userIDWord32+  {-# INLINE use_process_jobs' #-}   use_process_jobs' ::     Traversal' a ()   use_process_jobs' =     use_process_jobs . only True +-- |+--+-- >>> view close_fds (proc "echo" ["hello"])+-- False+-- >>> view (std_in) (proc "echo" ["hello"])+-- Inherit+-- >>> view cwd (proc "echo" ["hello"])+-- Nothing instance HasCreateProcess CreateProcess where   create_process =     id-  child_group f (CreateProcess csc cw en sti sto ste clf crg dct dcl cnc nss chg chu upj) =-    fmap (\chg' -> CreateProcess csc cw en sti sto ste clf crg dct dcl cnc nss chg' chu upj) (f chg)-  child_user f (CreateProcess csc cw en sti sto ste clf crg dct dcl cnc nss chg chu upj) =-    fmap (\chu' -> CreateProcess csc cw en sti sto ste clf crg dct dcl cnc nss chg chu' upj) (f chu)-  close_fds f (CreateProcess csc cw en sti sto ste clf crg dct dcl cnc nss chg chu upj) =-    fmap (\clf' -> CreateProcess csc cw en sti sto ste clf' crg dct dcl cnc nss chg chu upj) (f clf)-  create_group f (CreateProcess csc cw en sti sto ste clf crg dct dcl cnc nss chg chu upj) =-    fmap (\crg' -> CreateProcess csc cw en sti sto ste clf crg' dct dcl cnc nss chg chu upj) (f crg)-  create_new_console f (CreateProcess csc cw en sti sto ste clf crg dct dcl cnc nss chg chu upj) =-    fmap (\cnc' -> CreateProcess csc cw en sti sto ste clf crg dct dcl cnc' nss chg chu upj) (f cnc)-  cwd f (CreateProcess csc cw en sti sto ste clf crg dct dcl cnc nss chg chu upj) =-    fmap (\cw' -> CreateProcess csc cw' en sti sto ste clf crg dct dcl cnc nss chg chu upj) (f cw)-  delegate_ctlc f (CreateProcess csc cw en sti sto ste clf crg dct dcl cnc nss chg chu upj) =-    fmap (\dct' -> CreateProcess csc cw en sti sto ste clf crg dct' dcl cnc nss chg chu upj) (f dct)-  detach_console f (CreateProcess csc cw en sti sto ste clf crg dct dcl cnc nss chg chu upj) =-    fmap (\dcl' -> CreateProcess csc cw en sti sto ste clf crg dct dcl' cnc nss chg chu upj) (f dcl)-  env f (CreateProcess csc cw en sti sto ste clf crg dct dcl cnc nss chg chu upj) =-    fmap (\en' -> CreateProcess csc cw en' sti sto ste clf crg dct dcl cnc nss chg chu upj) (f en)-  new_session f (CreateProcess csc cw en sti sto ste clf crg dct dcl cnc nss chg chu upj) =-    fmap (\nss' -> CreateProcess csc cw en sti sto ste clf crg dct dcl cnc nss' chg chu upj) (f nss)-  std_err f (CreateProcess csc cw en sti sto ste clf crg dct dcl cnc nss chg chu upj) =-    fmap (\ste' -> CreateProcess csc cw en sti sto ste' clf crg dct dcl cnc nss chg chu upj) (f ste)-  std_in f (CreateProcess csc cw en sti sto ste clf crg dct dcl cnc nss chg chu upj) =-    fmap (\sti' -> CreateProcess csc cw en sti' sto ste clf crg dct dcl cnc nss chg chu upj) (f sti)-  std_out f (CreateProcess csc cw en sti sto ste clf crg dct dcl cnc nss chg chu upj) =-    fmap (\sto' -> CreateProcess csc cw en sti sto' ste clf crg dct dcl cnc nss chg chu upj) (f sto)-  use_process_jobs f (CreateProcess csc cw en sti sto ste clf crg dct dcl cnc nss chg chu upj) =-    fmap (CreateProcess csc cw en sti sto ste clf crg dct dcl cnc nss chg chu) (f upj)+  child_group f p =+    fmap (\x -> p {Process.child_group = x}) (f (Process.child_group p))+  child_user f p =+    fmap (\x -> p {Process.child_user = x}) (f (Process.child_user p))+  close_fds f p =+    fmap (\x -> p {Process.close_fds = x}) (f (Process.close_fds p))+  create_group f p =+    fmap (\x -> p {Process.create_group = x}) (f (Process.create_group p))+  create_new_console f p =+    fmap (\x -> p {Process.create_new_console = x}) (f (Process.create_new_console p))+  cwd f p =+    fmap (\x -> p {Process.cwd = x}) (f (Process.cwd p))+  delegate_ctlc f p =+    fmap (\x -> p {Process.delegate_ctlc = x}) (f (Process.delegate_ctlc p))+  detach_console f p =+    fmap (\x -> p {Process.detach_console = x}) (f (Process.detach_console p))+  env f p =+    fmap (\x -> p {Process.env = x}) (f (Process.env p))+  new_session f p =+    fmap (\x -> p {Process.new_session = x}) (f (Process.new_session p))+  std_err f p =+    fmap (\x -> p {Process.std_err = x}) (f (Process.std_err p))+  std_in f p =+    fmap (\x -> p {Process.std_in = x}) (f (Process.std_in p))+  std_out f p =+    fmap (\x -> p {Process.std_out = x}) (f (Process.std_out p))+  use_process_jobs f p =+    fmap (\x -> p {Process.use_process_jobs = x}) (f (Process.use_process_jobs p)) -class AsCreateProcess a where+-- | Type class for values that can be constructed from a @CreateProcess@.+--+-- >>> review reviewCreateProcess (proc "echo" ["hi"]) == proc "echo" ["hi"]+-- True+class ReviewCreateProcess a where+  reviewCreateProcess ::+    Review a CreateProcess++-- |+--+-- >>> review reviewCreateProcess (proc "echo" ["hi"]) == proc "echo" ["hi"]+-- True+instance ReviewCreateProcess CreateProcess where+  reviewCreateProcess = unto id+  {-# INLINE reviewCreateProcess #-}++-- | Type class for values with a prism into a @CreateProcess@.+--+-- >>> preview _CreateProcess (proc "echo" ["hi"]) == Just (proc "echo" ["hi"])+-- True+class (ReviewCreateProcess a) => AsCreateProcess a where   _CreateProcess ::     Prism' a CreateProcess +-- |+--+-- >>> preview _CreateProcess (proc "echo" ["hi"]) == Just (proc "echo" ["hi"])+-- True instance AsCreateProcess CreateProcess where   _CreateProcess =     id +-- |+--+-- >>> toListOf streams (proc "echo" ["hi"])+-- [Inherit,Inherit,Inherit]+-- >>> set streams CreatePipe (proc "echo" ["hi"]) ^. std_in+-- CreatePipe streams ::   Traversal' CreateProcess StdStream-streams f (CreateProcess csc cw en sti sto ste clf crg dct dcl cnc nss chg chu upj) =-  (\sti' sto' ste' -> CreateProcess csc cw en sti' sto' ste' clf crg dct dcl cnc nss chg chu upj) <$> f sti <*> f sto <*> f ste+streams f p =+  (\sti' sto' ste' -> p {Process.std_in = sti', Process.std_out = sto', Process.std_err = ste'})+    <$> f (Process.std_in p)+    <*> f (Process.std_out p)+    <*> f (Process.std_err p) +-- |+--+-- >>> toListOf streams1 (proc "echo" ["hi"])+-- [Inherit,Inherit,Inherit] streams1 ::   Traversal1' CreateProcess StdStream-streams1 f (CreateProcess csc cw en sti sto ste clf crg dct dcl cnc nss chg chu upj) =-  (\sti' sto' ste' -> CreateProcess csc cw en sti' sto' ste' clf crg dct dcl cnc nss chg chu upj) <$> f sti <.> f sto <.> f ste+streams1 f p =+  (\sti' sto' ste' -> p {Process.std_in = sti', Process.std_out = sto', Process.std_err = ste'})+    <$> f (Process.std_in p)+    <.> f (Process.std_out p)+    <.> f (Process.std_err p)
src/Control/Process/FD.hs view
@@ -1,44 +1,130 @@-{-# OPTIONS_GHC -Wall #-}-{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# OPTIONS_GHC -Wall #-} -module Control.Process.FD(-  HasFD(..)-, AsFD(..)-) where+module Control.Process.FD+  ( FD,+    GetFD (..),+    HasFD (..),+    ReviewFD (..),+    AsFD (..),+  )+where -import Control.Category((.), id)-import Control.Lens ( iso, Lens', Prism' )-import Data.Int ( Int32 )-import Foreign.C.Types ( CInt(CInt) )-import System.Posix.Internals ( FD )+import Control.Category (id, (.))+import Control.Lens (Getter, Lens', Prism', Review, iso, unto)+import Data.Int (Int32)+import Foreign.C.Types (CInt (CInt))+import System.Posix.Internals (FD) -class HasFD a where+-- $setup+-- >>> import Prelude+-- >>> import Control.Lens++-- | Type class for values that can be viewed as an @FD@.+--+-- >>> view getFD (3 :: FD)+-- 3+class GetFD a where+  getFD ::+    Getter a FD+  {-# INLINE getFDInt32 #-}+  getFDInt32 ::+    Getter a Int32+  getFDInt32 =+    getFD+      . iso+        (\(CInt x) -> x)+        CInt++-- |+--+-- >>> view getFD (3 :: FD)+-- 3+-- >>> view getFDInt32 (3 :: FD)+-- 3+instance GetFD FD where+  getFD = id+  {-# INLINE getFD #-}++-- | Type class for values with a lens into an @FD@.+--+-- >>> view fd (3 :: FD)+-- 3+class (GetFD a) => HasFD a where   fd ::     Lens' a FD+  {-# INLINE fdInt32 #-}   fdInt32 ::     Lens' a Int32   fdInt32 =-    fd .-      iso+    fd+      . iso         (\(CInt x) -> x)         CInt +-- |+--+-- >>> view fd (3 :: FD)+-- 3+-- >>> view fdInt32 (3 :: FD)+-- 3+-- >>> set fdInt32 7 (3 :: FD)+-- 7 instance HasFD FD where   fd =     id -class AsFD a where+-- | Type class for values that can be constructed from an @FD@.+--+-- >>> review reviewFD (3 :: FD) :: FD+-- 3+class ReviewFD a where+  reviewFD ::+    Review a FD+  {-# INLINE reviewFDInt32 #-}+  reviewFDInt32 ::+    Review a Int32+  reviewFDInt32 =+    reviewFD+      . iso+        (\(CInt x) -> x)+        CInt++-- |+--+-- >>> review reviewFD (3 :: FD) :: FD+-- 3+-- >>> review reviewFDInt32 7 :: FD+-- 7+instance ReviewFD FD where+  reviewFD = unto id+  {-# INLINE reviewFD #-}++-- | Type class for values with a prism into an @FD@.+--+-- >>> preview _FD (3 :: FD)+-- Just 3+class (ReviewFD a) => AsFD a where   _FD ::     Prism' a FD+  {-# INLINE _FDInt32 #-}   _FDInt32 ::     Prism' a Int32   _FDInt32 =-    _FD .-      iso+    _FD+      . iso         (\(CInt x) -> x)         CInt +-- |+--+-- >>> preview _FD (3 :: FD)+-- Just 3+-- >>> preview _FDInt32 (3 :: FD)+-- Just 3+-- >>> review _FDInt32 7 :: FD+-- 7 instance AsFD FD where   _FD =     id
src/Control/Process/GroupID.hs view
@@ -1,28 +1,88 @@-{-# OPTIONS_GHC -Wall #-}-{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# OPTIONS_GHC -Wall #-} -module Control.Process.GroupID(-  HasGroupID(..)-, AsGroupID(..)-) where+module Control.Process.GroupID+  ( GroupID,+    GetGroupID (..),+    HasGroupID (..),+    ReviewGroupID (..),+    AsGroupID (..),+  )+where -import Control.Category(id)-import Control.Lens ( Lens', Prism' )-import System.Process.Internals ( GroupID )+import Control.Category (id)+import Control.Lens (Getter, Lens', Prism', Review, unto)+import System.Process.Internals (GroupID) -class HasGroupID a where+-- $setup+-- >>> import Prelude+-- >>> import Control.Lens++-- | Type class for values that can be viewed as a @GroupID@.+--+-- >>> view getGroupID (42 :: GroupID)+-- 42+class GetGroupID a where+  getGroupID ::+    Getter a GroupID++-- |+--+-- >>> view getGroupID (42 :: GroupID)+-- 42+instance GetGroupID GroupID where+  getGroupID = id+  {-# INLINE getGroupID #-}++-- | Type class for values with a lens into a @GroupID@.+--+-- >>> view groupID (42 :: GroupID)+-- 42+class (GetGroupID a) => HasGroupID a where   groupID ::     Lens' a GroupID +-- |+--+-- >>> view groupID (42 :: GroupID)+-- 42+-- >>> set groupID 99 (42 :: GroupID)+-- 99 instance HasGroupID GroupID where   groupID =     id -class AsGroupID a where+-- | Type class for values that can be constructed from a @GroupID@.+--+-- >>> review reviewGroupID (42 :: GroupID) :: GroupID+-- 42+class ReviewGroupID a where+  reviewGroupID ::+    Review a GroupID++-- |+--+-- >>> review reviewGroupID (42 :: GroupID) :: GroupID+-- 42+instance ReviewGroupID GroupID where+  reviewGroupID = unto id+  {-# INLINE reviewGroupID #-}++-- | Type class for values with a prism into a @GroupID@.+--+-- >>> preview _GroupID (42 :: GroupID)+-- Just 42+class (ReviewGroupID a) => AsGroupID a where   _GroupID ::     Prism' a GroupID +-- |+--+-- >>> preview _GroupID (42 :: GroupID)+-- Just 42+-- >>> review _GroupID 42 :: GroupID+-- 42 instance AsGroupID GroupID where   _GroupID =     id
src/Control/Process/Handle.hs view
@@ -1,39 +1,113 @@-{-# OPTIONS_GHC -Wall #-}-{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE LambdaCase #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# OPTIONS_GHC -Wall #-} -module Control.Process.Handle(-  HasHandle(..)-, AsHandle(..)-) where+module Control.Process.Handle+  ( Handle,+    GetHandle (..),+    HasHandle (..),+    ReviewHandle (..),+    AsHandle (..),+  )+where -import Control.Category(id)-import Control.Lens ( prism', Lens', Prism' )-import Data.Maybe ( Maybe(Nothing, Just) )-import System.IO ( Handle )-import System.Process ( StdStream(UseHandle) )+import Control.Category (id)+import Control.Lens (Getter, Lens', Prism', Review, prism', unto)+import Data.Maybe (Maybe (Just, Nothing))+import System.IO (Handle)+import System.Process (StdStream (UseHandle)) -class HasHandle a where+-- $setup+-- >>> import Prelude+-- >>> import Control.Lens+-- >>> import System.IO (stdin, stdout)+-- >>> import System.Process (StdStream(..))++-- | Type class for values that can be viewed as a @Handle@.+--+-- >>> view getHandle stdin+-- {handle: <stdin>}+class GetHandle a where+  getHandle ::+    Getter a Handle++-- |+--+-- >>> view getHandle stdin+-- {handle: <stdin>}+instance GetHandle Handle where+  getHandle = id+  {-# INLINE getHandle #-}++-- | Type class for values with a lens into a @Handle@.+--+-- >>> view handle stdin+-- {handle: <stdin>}+class (GetHandle a) => HasHandle a where   handle ::     Lens' a Handle +-- |+--+-- >>> view handle stdin+-- {handle: <stdin>} instance HasHandle Handle where   handle =     id -class AsHandle a where+-- | Type class for values that can be constructed from a @Handle@.+--+-- >>> review reviewHandle stdin :: Handle+-- {handle: <stdin>}+class ReviewHandle a where+  reviewHandle ::+    Review a Handle++-- |+--+-- >>> review reviewHandle stdin :: Handle+-- {handle: <stdin>}+instance ReviewHandle Handle where+  reviewHandle = unto id+  {-# INLINE reviewHandle #-}++-- |+--+-- >>> review reviewHandle stdout :: StdStream+-- UseHandle {handle: <stdout>}+instance ReviewHandle StdStream where+  reviewHandle = unto UseHandle+  {-# INLINE reviewHandle #-}++-- | Type class for values with a prism into a @Handle@.+--+-- >>> preview _Handle stdin+-- Just {handle: <stdin>}+class (ReviewHandle a) => AsHandle a where   _Handle ::     Prism' a Handle +-- |+--+-- >>> preview _Handle stdin+-- Just {handle: <stdin>} instance AsHandle Handle where   _Handle =     id +-- |+--+-- >>> preview _Handle (UseHandle stdout)+-- Just {handle: <stdout>}+-- >>> preview _Handle (Inherit :: StdStream)+-- Nothing+-- >>> review _Handle stdout :: StdStream+-- UseHandle {handle: <stdout>} instance AsHandle StdStream where   _Handle =     prism'       UseHandle-      (\case-        UseHandle a -> Just a-        _ -> Nothing+      ( \case+          UseHandle a -> Just a+          _ -> Nothing       )
src/Control/Process/Pid.hs view
@@ -1,44 +1,130 @@-{-# OPTIONS_GHC -Wall #-}-{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# OPTIONS_GHC -Wall #-} -module Control.Process.Pid(-  HasPid(..)-, AsPid(..)-) where+module Control.Process.Pid+  ( Pid,+    GetPid (..),+    HasPid (..),+    ReviewPid (..),+    AsPid (..),+  )+where -import Control.Category((.), id)-import Control.Lens ( iso, Lens', Prism' )-import Data.Int ( Int32 )-import System.Posix.Types ( CPid(CPid) )-import System.Process ( Pid )+import Control.Category (id, (.))+import Control.Lens (Getter, Lens', Prism', Review, iso, unto)+import Data.Int (Int32)+import System.Posix.Types (CPid (CPid))+import System.Process (Pid) -class HasPid a where+-- $setup+-- >>> import Prelude+-- >>> import Control.Lens++-- | Type class for values that can be viewed as a @Pid@.+--+-- >>> view viewPid (CPid 42)+-- 42+class GetPid a where+  viewPid ::+    Getter a Pid+  {-# INLINE viewPidInt32 #-}+  viewPidInt32 ::+    Getter a Int32+  viewPidInt32 =+    viewPid+      . iso+        (\(CPid x) -> x)+        CPid++-- |+--+-- >>> view viewPid (CPid 42)+-- 42+-- >>> view viewPidInt32 (CPid 42)+-- 42+instance GetPid Pid where+  viewPid = id+  {-# INLINE viewPid #-}++-- | Type class for values with a lens into a @Pid@.+--+-- >>> view pid (CPid 42)+-- 42+class (GetPid a) => HasPid a where   pid ::     Lens' a Pid+  {-# INLINE pidInt32 #-}   pidInt32 ::     Lens' a Int32   pidInt32 =-    pid .-      iso+    pid+      . iso         (\(CPid x) -> x)         CPid +-- |+--+-- >>> view pid (CPid 42)+-- 42+-- >>> view pidInt32 (CPid 42)+-- 42+-- >>> set pidInt32 99 (CPid 42)+-- 99 instance HasPid Pid where   pid =     id -class AsPid a where+-- | Type class for values that can be constructed from a @Pid@.+--+-- >>> review reviewPid (CPid 42) :: Pid+-- 42+class ReviewPid a where+  reviewPid ::+    Review a Pid+  {-# INLINE reviewPidInt32 #-}+  reviewPidInt32 ::+    Review a Int32+  reviewPidInt32 =+    reviewPid+      . iso+        (\(CPid x) -> x)+        CPid++-- |+--+-- >>> review reviewPid (CPid 42) :: Pid+-- 42+-- >>> review reviewPidInt32 99 :: Pid+-- 99+instance ReviewPid Pid where+  reviewPid = unto id+  {-# INLINE reviewPid #-}++-- | Type class for values with a prism into a @Pid@.+--+-- >>> preview _Pid (CPid 42)+-- Just 42+class (ReviewPid a) => AsPid a where   _Pid ::     Prism' a Pid+  {-# INLINE _PidInt32 #-}   _PidInt32 ::     Prism' a Int32   _PidInt32 =-    _Pid .-      iso+    _Pid+      . iso         (\(CPid x) -> x)         CPid +-- |+--+-- >>> preview _Pid (CPid 42)+-- Just 42+-- >>> preview _PidInt32 (CPid 42)+-- Just 42+-- >>> review _PidInt32 99 :: Pid+-- 99 instance AsPid Pid where   _Pid =     id
src/Control/Process/Process.hs view
@@ -1,143 +1,155 @@-{-# OPTIONS_GHC -Wall #-} {-# LANGUAGE NoImplicitPrelude #-}+{-# OPTIONS_GHC -Wall #-} -module Control.Process.Process(-  module Process-, readCreateProcessWithExitCode-, readProcessWithExitCode-, waitForProcess-, getProcessExitCode-, getProcessExitCodeBool-) where+module Control.Process.Process+  ( module Process,+    readCreateProcessWithExitCode,+    readProcessWithExitCode,+    waitForProcess,+    getProcessExitCode,+    getProcessExitCodeBool,+    getPid,+  )+where -import Control.Applicative ( Applicative(pure) )-import Control.Category ( Category((.)) )-import Control.Exception ( Exception )+import Control.Applicative (Applicative (pure))+import Control.Category (Category ((.)))+import Control.Exception (Exception) import Control.Exitcode-    ( ExitcodeT,-      fromExitCode',-      liftExitcode,-      hoistExitcode,-      tryExitcode,-      _Exitcode1,-      liftTryExitcode )-import Control.Lens ( Identity(runIdentity), set )-import Control.Monad ( Monad((>>=)) )-import Control.Monad.Except ( ExceptT(..) )-import Data.Bifunctor ( Bifunctor(bimap) )-import Data.Bool ( Bool )-import Data.Maybe ( Maybe(..), isJust, maybe )-import Data.String ( String )-import System.FilePath( FilePath )-import System.IO ( IO )-import System.Process as Process(-    createProcess-  , createProcess_-  , shell-  , proc-  , CreateProcess()-  , CmdSpec(..)-  , StdStream(..)-  , ProcessHandle-  , callProcess-  , callCommand-  , spawnProcess-  , readCreateProcess-  , readProcess-  , withCreateProcess-  , cleanupProcess-  , showCommandForUser-  , Pid-  , getPid-  , getCurrentPid-  , terminateProcess-  , interruptProcessGroupOf-  , createPipe-  , createPipeFd+  ( Exitcode,+    bimapExitcode,+    fromExitCode',+    hoistExitcode,+    liftTryExitcode,+    mkExitSuccess,+    tryExitcode,   )-import qualified System.Process as P(readCreateProcessWithExitCode, readProcessWithExitCode, waitForProcess, getProcessExitCode)+import Control.Monad (Monad ((>>=)))+import Control.Monad.Except (ExceptT (..))+import Data.Bool (Bool)+import Data.Function (const)+import Data.Functor.Identity (runIdentity)+import Data.Maybe (Maybe (..), isJust, maybe)+import Data.String (String)+import System.FilePath (FilePath)+import System.IO (IO)+import System.Process as Process+  ( CmdSpec (..),+    CreateProcess (),+    Pid,+    ProcessHandle,+    StdStream (..),+    callCommand,+    callProcess,+    cleanupProcess,+    createPipe,+    createPipeFd,+    createProcess,+    createProcess_,+    getCurrentPid,+    interruptProcessGroupOf,+    proc,+    readCreateProcess,+    readProcess,+    shell,+    showCommandForUser,+    spawnProcess,+    terminateProcess,+    withCreateProcess,+  )+import qualified System.Process as P (getProcessExitCode, getPid, readCreateProcessWithExitCode, readProcessWithExitCode, waitForProcess) +getPid :: ProcessHandle -> IO (Maybe Pid)+getPid = P.getPid+ -- | @readCreateProcessWithExitCode@ works exactly like 'readProcessWithExitCode' except that it -- lets you pass 'CreateProcess' giving better flexibility. -- -- Note that @Handle@s provided for @std_in@, @std_out@, or @std_err@ via the CreateProcess -- record will be ignored.+{-# INLINE readCreateProcessWithExitCode #-} readCreateProcessWithExitCode ::-  Exception e' =>-  CreateProcess-  -> String -- ^ standard input-  -> ExitcodeT (ExceptT e' IO) (String, String) (String, String) -- ^ exitcode, stdout, stderr+  (Exception e') =>+  CreateProcess ->+  -- | standard input+  String ->+  -- | exitcode, stdout, stderr+  Exitcode (String, String) (ExceptT e' IO) (String, String) readCreateProcessWithExitCode p a =-  tryExitcode (liftExitcode (P.readCreateProcessWithExitCode p a)) >>= \(x, y, z) ->-    hoistExitcode (pure . runIdentity) (set _Exitcode1 (y, z) (fromExitCode' x))+  tryExitcode (mkExitSuccess (P.readCreateProcessWithExitCode p a)) >>= \(x, y, z) ->+    hoistExitcode (pure . runIdentity) (bimapExitcode (const (y, z)) (const (y, z)) (fromExitCode' x)) +{-# INLINE readProcessWithExitCode #-} readProcessWithExitCode ::-  Exception e' =>-  FilePath -- ^ Filename of the executable (see 'RawCommand' for details)-  -> [String] -- ^ any arguments-  -> String -- ^ standard input-  -> ExitcodeT (ExceptT e' IO) (String, String) (String, String) -- ^ exitcode, stdout, stderr+  (Exception e') =>+  -- | Filename of the executable (see 'RawCommand' for details)+  FilePath ->+  -- | any arguments+  [String] ->+  -- | standard input+  String ->+  -- | exitcode, stdout, stderr+  Exitcode (String, String) (ExceptT e' IO) (String, String) readProcessWithExitCode p a i =-  tryExitcode (liftExitcode (P.readProcessWithExitCode p a i)) >>= \(x, y, z) ->-    hoistExitcode (pure . runIdentity) (set _Exitcode1 (y, z) (fromExitCode' x))--{- | Waits for the specified process to terminate, and returns its exit code.-On Unix systems, may throw 'UserInterrupt' when using 'delegate_ctlc'.--GHC Note: in order to call @waitForProcess@ without blocking all the-other threads in the system, you must compile the program with-@-threaded@.--Note that it is safe to call @waitForProcess@ for the same process in multiple-threads. When the process ends, threads blocking on this call will wake in-FIFO order. When using 'delegate_ctlc' and the process is interrupted, only-the first waiting thread will throw 'UserInterrupt'.--(/Since: 1.2.0.0/) On Unix systems, a negative value @'ExitFailure' -/signum/@-indicates that the child was terminated by signal @/signum/@.-The signal numbers are platform-specific, so to test for a specific signal use-the constants provided by "System.Posix.Signals" in the @unix@ package.-Note: core dumps are not reported, use "System.Posix.Process" if you need this-detail.+  tryExitcode (mkExitSuccess (P.readProcessWithExitCode p a i)) >>= \(x, y, z) ->+    hoistExitcode (pure . runIdentity) (bimapExitcode (const (y, z)) (const (y, z)) (fromExitCode' x)) --}+-- | Waits for the specified process to terminate, and returns its exit code.+-- On Unix systems, may throw 'UserInterrupt' when using 'delegate_ctlc'.+--+-- GHC Note: in order to call @waitForProcess@ without blocking all the+-- other threads in the system, you must compile the program with+-- @-threaded@.+--+-- Note that it is safe to call @waitForProcess@ for the same process in multiple+-- threads. When the process ends, threads blocking on this call will wake in+-- FIFO order. When using 'delegate_ctlc' and the process is interrupted, only+-- the first waiting thread will throw 'UserInterrupt'.+--+-- (/Since: 1.2.0.0/) On Unix systems, a negative value @'ExitFailure' -/signum/@+-- indicates that the child was terminated by signal @/signum/@.+-- The signal numbers are platform-specific, so to test for a specific signal use+-- the constants provided by "System.Posix.Signals" in the @unix@ package.+-- Note: core dumps are not reported, use "System.Posix.Process" if you need this+-- detail.+{-# INLINE waitForProcess #-} waitForProcess ::-  Exception e' =>-  ProcessHandle-  -> ExitcodeT (ExceptT e' IO) () ()+  (Exception e') =>+  ProcessHandle ->+  Exitcode () (ExceptT e' IO) () waitForProcess h =-  tryExitcode (liftExitcode (P.waitForProcess h)) >>= \x ->+  tryExitcode (mkExitSuccess (P.waitForProcess h)) >>= \x ->     hoistExitcode (pure . runIdentity) (fromExitCode' x) -{- |-This is a non-blocking version of 'waitForProcess'.  If the process is-still running, 'Nothing' is returned.  If the process has exited, then-@'Just' e@ is returned where @e@ is the exit code of the process.--On Unix systems, see 'waitForProcess' for the meaning of exit codes-when the process died as the result of a signal. May throw-'UserInterrupt' when using 'delegate_ctlc'.--}+-- |+-- This is a non-blocking version of 'waitForProcess'.  If the process is+-- still running, 'Nothing' is returned.  If the process has exited, then+-- @'Just' e@ is returned where @e@ is the exit code of the process.+--+-- On Unix systems, see 'waitForProcess' for the meaning of exit codes+-- when the process died as the result of a signal. May throw+-- 'UserInterrupt' when using 'delegate_ctlc'.+{-# INLINE getProcessExitCode #-} getProcessExitCode ::-  Exception e' =>-  ProcessHandle-  -> ExitcodeT (ExceptT e' IO) (Maybe ()) (Maybe ())+  (Exception e') =>+  ProcessHandle ->+  Exitcode (Maybe ()) (ExceptT e' IO) (Maybe ()) getProcessExitCode h =-  liftTryExitcode (P.getProcessExitCode h) >>=-    maybe (pure Nothing) (hoistExitcode (pure . runIdentity) . set _Exitcode1 (Just ()) . fromExitCode')--{- |-This is a non-blocking version of 'waitForProcess'.  If the process is-still running, 'Nothing' is returned.  If the process has exited, then-@'Just' e@ is returned where @e@ is the exit code of the process.+  liftTryExitcode (P.getProcessExitCode h)+    >>= maybe (pure Nothing) (hoistExitcode (pure . runIdentity) . bimapExitcode (const (Just ())) (const (Just ())) . fromExitCode') -On Unix systems, see 'waitForProcess' for the meaning of exit codes-when the process died as the result of a signal. May throw-'UserInterrupt' when using 'delegate_ctlc'.--}+-- |+-- This is a non-blocking version of 'waitForProcess'.  If the process is+-- still running, 'Nothing' is returned.  If the process has exited, then+-- @'Just' e@ is returned where @e@ is the exit code of the process.+--+-- On Unix systems, see 'waitForProcess' for the meaning of exit codes+-- when the process died as the result of a signal. May throw+-- 'UserInterrupt' when using 'delegate_ctlc'.+{-# INLINE getProcessExitCodeBool #-} getProcessExitCodeBool ::-  Exception e' =>-  ProcessHandle-  -> ExitcodeT (ExceptT e' IO) Bool Bool-getProcessExitCodeBool =-  bimap isJust isJust . getProcessExitCode+  (Exception e') =>+  ProcessHandle ->+  Exitcode Bool (ExceptT e' IO) Bool+getProcessExitCodeBool h =+  bimapExitcode isJust isJust (getProcessExitCode h)
src/Control/Process/ProcessHandle.hs view
@@ -1,16 +1,30 @@-{-# OPTIONS_GHC -Wall #-} {-# LANGUAGE NoImplicitPrelude #-}+{-# OPTIONS_GHC -Wall #-} -module Control.Process.ProcessHandle(-  HasProcessHandle(..)-, AsProcessHandle(..)-) where+module Control.Process.ProcessHandle+  ( ProcessHandle,+    GetProcessHandle (..),+    HasProcessHandle (..),+    ReviewProcessHandle (..),+    AsProcessHandle (..),+  )+where -import Control.Category(id)-import System.Process ( ProcessHandle )-import Control.Lens ( Lens', Prism' )+import Control.Category (id)+import Control.Lens (Getter, Lens', Prism', Review, unto)+import System.Process (ProcessHandle) -class HasProcessHandle a where+-- | Type class for values that can be viewed as a @ProcessHandle@.+class GetProcessHandle a where+  getProcessHandle ::+    Getter a ProcessHandle++instance GetProcessHandle ProcessHandle where+  getProcessHandle = id+  {-# INLINE getProcessHandle #-}++-- | Type class for values with a lens into a @ProcessHandle@.+class (GetProcessHandle a) => HasProcessHandle a where   processHandle ::     Lens' a ProcessHandle @@ -18,7 +32,17 @@   processHandle =     id -class AsProcessHandle a where+-- | Type class for values that can be constructed from a @ProcessHandle@.+class ReviewProcessHandle a where+  reviewProcessHandle ::+    Review a ProcessHandle++instance ReviewProcessHandle ProcessHandle where+  reviewProcessHandle = unto id+  {-# INLINE reviewProcessHandle #-}++-- | Type class for values with a prism into a @ProcessHandle@.+class (ReviewProcessHandle a) => AsProcessHandle a where   _ProcessHandle ::     Prism' a ProcessHandle 
src/Control/Process/StdStream.hs view
@@ -1,63 +1,155 @@-{-# OPTIONS_GHC -Wall #-}-{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE LambdaCase #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# OPTIONS_GHC -Wall #-} -module Control.Process.StdStream(-  StdStream(..)-, AsStdStream(..)-, HasStdStream(..)-) where+module Control.Process.StdStream+  ( StdStream (..),+    GetStdStream (..),+    HasStdStream (..),+    ReviewStdStream (..),+    AsStdStream (..),+  )+where -import Control.Category ( Category(id, (.)) )-import Control.Lens ( prism', Lens', Prism' )-import Data.Maybe ( Maybe(Nothing, Just) )-import System.Process ( StdStream(..) )+import Control.Category (id, (.))+import Control.Lens (Getter, Lens', Prism', Review, prism', unto)+import Data.Maybe (Maybe (Just, Nothing))+import System.IO (Handle)+import System.Process (StdStream (..)) -class AsStdStream a where+-- $setup+-- >>> import Prelude+-- >>> import Control.Lens+-- >>> import System.IO (stdin, stdout)++-- | Type class for values that can be viewed as a @StdStream@.+--+-- >>> view getStdStream Inherit+-- Inherit+class GetStdStream a where+  getStdStream ::+    Getter a StdStream++-- |+--+-- >>> view getStdStream Inherit+-- Inherit+instance GetStdStream StdStream where+  getStdStream = id+  {-# INLINE getStdStream #-}++-- | Type class for values with a lens into a @StdStream@.+--+-- >>> view stdStream Inherit+-- Inherit+class (GetStdStream a) => HasStdStream a where+  stdStream ::+    Lens' a StdStream++-- |+--+-- >>> view stdStream Inherit+-- Inherit+-- >>> set stdStream CreatePipe Inherit+-- CreatePipe+instance HasStdStream StdStream where+  stdStream =+    id++-- | Type class for values that can be constructed from a @StdStream@.+--+-- >>> review reviewStdStream Inherit :: StdStream+-- Inherit+class ReviewStdStream a where+  reviewStdStream ::+    Review a StdStream++-- |+--+-- >>> review reviewStdStream Inherit :: StdStream+-- Inherit+instance ReviewStdStream StdStream where+  reviewStdStream = unto id+  {-# INLINE reviewStdStream #-}++-- | Type class for values with a prism into a @StdStream@.+--+-- >>> preview _StdStream Inherit+-- Just Inherit+class (ReviewStdStream a) => AsStdStream a where   _StdStream ::     Prism' a StdStream+  {-# INLINE _Inherit #-}   _Inherit ::     Prism' a ()   _Inherit =     _StdStream . _Inherit+  {-# INLINE _CreatePipe #-}   _CreatePipe ::     Prism' a ()   _CreatePipe =     _StdStream . _CreatePipe+  {-# INLINE _UseHandle #-}+  _UseHandle ::+    Prism' a Handle+  _UseHandle =+    _StdStream . _UseHandle+  {-# INLINE _NoStream #-}   _NoStream ::     Prism' a ()   _NoStream =     _StdStream . _NoStream +-- |+--+-- >>> preview _Inherit Inherit+-- Just ()+-- >>> preview _Inherit CreatePipe+-- Nothing+-- >>> preview _CreatePipe CreatePipe+-- Just ()+-- >>> preview _UseHandle (UseHandle stdout)+-- Just {handle: <stdout>}+-- >>> preview _UseHandle Inherit+-- Nothing+-- >>> preview _NoStream NoStream+-- Just ()+-- >>> review _Inherit () :: StdStream+-- Inherit+-- >>> review _CreatePipe () :: StdStream+-- CreatePipe+-- >>> review _UseHandle stdout :: StdStream+-- UseHandle {handle: <stdout>}+-- >>> review _NoStream () :: StdStream+-- NoStream instance AsStdStream StdStream where   _StdStream =     id   _Inherit =     prism'       (\() -> Inherit)-      (\case-        Inherit -> Just ()-        _ -> Nothing+      ( \case+          Inherit -> Just ()+          _ -> Nothing       )   _CreatePipe =     prism'       (\() -> CreatePipe)-      (\case-        CreatePipe -> Just ()-        _ -> Nothing+      ( \case+          CreatePipe -> Just ()+          _ -> Nothing       )+  _UseHandle =+    prism'+      UseHandle+      ( \case+          UseHandle a -> Just a+          _ -> Nothing+      )   _NoStream =     prism'       (\() -> NoStream)-      (\case-        NoStream -> Just ()-        _ -> Nothing+      ( \case+          NoStream -> Just ()+          _ -> Nothing       )--class HasStdStream a where-  stdStream ::-    Lens' a StdStream--instance HasStdStream StdStream where-  stdStream =-    id
src/Control/Process/UserID.hs view
@@ -1,44 +1,130 @@-{-# OPTIONS_GHC -Wall #-}-{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# OPTIONS_GHC -Wall #-} -module Control.Process.UserID(-  HasUserID(..)-, AsUserID(..)-) where+module Control.Process.UserID+  ( UserID,+    GetUserID (..),+    HasUserID (..),+    ReviewUserID (..),+    AsUserID (..),+  )+where -import Control.Category((.), id)-import Control.Lens ( iso, Lens', Prism' )-import Data.Word ( Word32 )-import System.Posix.Types ( CUid(CUid) )-import System.Process.Internals ( UserID )+import Control.Category (id, (.))+import Control.Lens (Getter, Lens', Prism', Review, iso, unto)+import Data.Word (Word32)+import System.Posix.Types (CUid (CUid))+import System.Process.Internals (UserID) -class HasUserID a where+-- $setup+-- >>> import Prelude+-- >>> import Control.Lens++-- | Type class for values that can be viewed as a @UserID@.+--+-- >>> view getUserID (CUid 1000)+-- 1000+class GetUserID a where+  getUserID ::+    Getter a UserID+  {-# INLINE getUserIDWord32 #-}+  getUserIDWord32 ::+    Getter a Word32+  getUserIDWord32 =+    getUserID+      . iso+        (\(CUid x) -> x)+        CUid++-- |+--+-- >>> view getUserID (CUid 1000)+-- 1000+-- >>> view getUserIDWord32 (CUid 1000)+-- 1000+instance GetUserID UserID where+  getUserID = id+  {-# INLINE getUserID #-}++-- | Type class for values with a lens into a @UserID@.+--+-- >>> view userID (CUid 1000)+-- 1000+class (GetUserID a) => HasUserID a where   userID ::     Lens' a UserID+  {-# INLINE userIDWord32 #-}   userIDWord32 ::     Lens' a Word32   userIDWord32 =-    userID .-      iso+    userID+      . iso         (\(CUid x) -> x)         CUid +-- |+--+-- >>> view userID (CUid 1000)+-- 1000+-- >>> view userIDWord32 (CUid 1000)+-- 1000+-- >>> set userIDWord32 0 (CUid 1000)+-- 0 instance HasUserID UserID where   userID =     id -class AsUserID a where+-- | Type class for values that can be constructed from a @UserID@.+--+-- >>> review reviewUserID (CUid 1000) :: UserID+-- 1000+class ReviewUserID a where+  reviewUserID ::+    Review a UserID+  {-# INLINE reviewUserIDWord32 #-}+  reviewUserIDWord32 ::+    Review a Word32+  reviewUserIDWord32 =+    reviewUserID+      . iso+        (\(CUid x) -> x)+        CUid++-- |+--+-- >>> review reviewUserID (CUid 1000) :: UserID+-- 1000+-- >>> review reviewUserIDWord32 42 :: UserID+-- 42+instance ReviewUserID UserID where+  reviewUserID = unto id+  {-# INLINE reviewUserID #-}++-- | Type class for values with a prism into a @UserID@.+--+-- >>> preview _UserID (CUid 1000)+-- Just 1000+class (ReviewUserID a) => AsUserID a where   _UserID ::     Prism' a UserID+  {-# INLINE _UserIDWord32 #-}   _UserIDWord32 ::     Prism' a Word32   _UserIDWord32 =-    _UserID .-      iso+    _UserID+      . iso         (\(CUid x) -> x)         CUid +-- |+--+-- >>> preview _UserID (CUid 1000)+-- Just 1000+-- >>> preview _UserIDWord32 (CUid 1000)+-- Just 1000+-- >>> review _UserIDWord32 42 :: UserID+-- 42 instance AsUserID UserID where   _UserID =     id
+ test/Main.hs view
@@ -0,0 +1,18 @@+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}++module Main (main) where++import System.Exit (exitWith)+import System.Process (rawSystem)++main :: IO ()+main =+  exitWith+    =<< rawSystem+      "cabal"+      [ "repl",+        "--with-compiler=doctest",+        "--repl-options=-w",+        "--repl-options=-Wdefault",+        "lib:exitcode"+      ]
− test/Tests.hs
@@ -1,127 +0,0 @@-import           Control.Lens              (review, (^.), (^?))-import           Control.Monad.Trans.Maybe (MaybeT (MaybeT))-import           Data.Functor.Classes      (Eq1)-import           Data.Functor.Identity     (Identity (..), runIdentity)-import           Data.Monoid               ((<>))--import           Hedgehog                  (forAll, property, (===))-import qualified Hedgehog.Gen              as Gen-import           Hedgehog.Internal.Gen     (MonadGen)-import qualified Hedgehog.Range            as Range-import           Test.QuickCheck           (Arbitrary)-import           Test.QuickCheck.Checkers  (EqProp (..), Test, TestBatch, eq)-import           Test.QuickCheck.Classes   (applicative, functor)-import           Test.Tasty                (TestTree, defaultMain, testGroup)-import           Test.Tasty.Hedgehog       (testProperty)-import           Test.Tasty.HUnit          (testCase, (@?=))-import qualified Test.Tasty.QuickCheck     as TQC--import           Control.Exitcode          (Exitcode, ExitcodeT, exitCode,-                                            exitfailure0, exitsuccess,-                                            exitsuccess0, runExitcode,-                                            runExitcodeT, _ExitFailure,-                                            _ExitSuccess, ExitcodeT0)--import           System.Exit               (ExitCode (..))--newtype EW f e a = EW { unEW :: ExitcodeT f e a } deriving (Eq, Show)--instance (Monad f, Arbitrary e, Arbitrary a) => Arbitrary (EW f e a) where-  arbitrary = fmap (EW . pure) TQC.arbitrary--instance Functor f => Functor (EW f e) where-  fmap f = EW . fmap f . unEW--instance Monad f => Applicative (EW f e) where-  pure = EW . pure-  EW f <*> EW a = EW (f <*> a)--instance (Eq1 f, Eq e, Eq a) => EqProp (EW f e a) where-  (=-=) = eq--type CheckMe = EW [] String (Integer, Integer, Integer)--nonZero :: MonadGen m => m Int-nonZero =-  let allOfTheInts = Range.linear (minBound :: Int) (maxBound :: Int)-   in Gen.filter (/= 0) (Gen.int allOfTheInts)--main :: IO ()-main = defaultMain test_Exitcode--test_Exitcode :: TestTree-test_Exitcode =-  testGroup "Exitcode" [-    tastyCheckersBatch $ functor (undefined :: CheckMe)-  , tastyCheckersBatch $ applicative (undefined :: CheckMe)-  , applicativeTest-  , exitFailureTraversalTest-  , exitSuccessPrismTest-  , exitfailure0Test-  , exitCodePrismTest-  ]--applicativeTest :: TestTree-applicativeTest =-  testGroup "Applicative" [-    testCase "Sticks to the Right" $-      pure (<> "bar") <*> pure "foo" @?= (exitsuccess "foobar" :: Exitcode String String)-  ]--exitFailureTraversalTest :: TestTree-exitFailureTraversalTest =-  testGroup "_ExitFailure Traversal" [-    testProperty "view non-zero input" . property $-      forAll nonZero >>= (\n -> (exitfailure0 n :: ExitcodeT0 Identity) ^? _ExitFailure === Just ((), n))-  , testCase "view 0" $-      (exitfailure0 0 :: ExitcodeT0 Identity) ^? _ExitFailure @?= Nothing-  ]--exitSuccessPrismTest :: TestTree-exitSuccessPrismTest =-  testGroup "_ExitSuccess Prism" [-    testCase "review" $-      review _ExitSuccess () @?= (exitsuccess0 :: ExitcodeT Identity () ())-  , testCase "view exitsuccess0" $-      (exitsuccess0 :: ExitcodeT Identity () ()) ^? _ExitSuccess @?= Just ()-  , testProperty "view exitfailure0 non-zero" . property $-      forAll nonZero >>= (\n -> exitfailure0 n ^? _ExitSuccess === Nothing)-  , testCase "view exitfailure0 0" $-      exitfailure0 0 ^? _ExitSuccess @?= Just ()-  ]--exitfailure0Test :: TestTree-exitfailure0Test =-  testGroup "exitfailure0" [-    testProperty "non-zero input" . property $-      forAll nonZero >>= (\n ->-        runExitcode (exitfailure0 n) === Left ((), n))-  , testCase "0" $-      runExitcode (exitfailure0 0) @?= Right ()-  ]--exitCodePrismTest :: TestTree-exitCodePrismTest =-  testGroup "exitCode Prism" [-    testProperty "`exitfailure0 n`, where n is non-zero" . property $-      forAll nonZero >>= \n -> (review exitCode (exitfailure0 n)) === Identity (ExitFailure n)-  , testCase "review `exitfailure 0`" $-      runIdentity (review exitCode (exitfailure0 0)) @?= ExitSuccess-  , testCase "review `exitsuccess0`" $-      runIdentity (review exitCode exitsuccess0) @?= ExitSuccess-  , testProperty "view ExitFailure n, where n is non-zero" . property $-      forAll nonZero >>= (\n -> Identity (ExitFailure n) ^? exitCode === Just (exitfailure0 n))-  , testCase "view ExitFailure 0" $-      let _ = ""-      in  runExitcodeT (Identity (ExitFailure 0) ^. exitCode) @?= (MaybeT (Identity Nothing))-  , testCase "view ExitSuccess" $-      Identity ExitSuccess ^? exitCode @?= Just exitsuccess0-  ]--tastyCheckersBatch :: TestBatch -> TestTree-tastyCheckersBatch (name, tests) =-  testGroup (name <> " laws") (tastyCheckersProperty <$> tests)--tastyCheckersProperty :: Test -> TestTree-tastyCheckersProperty =-  uncurry TQC.testProperty