module Data.Gibberish.Monad.Pass
  ( Pass (),
    PassT (..),
    runPass,
    evalPass,
    usingPass,
    runPassT,
    evalPassT,
    usingPassT,
    module Control.Monad.Random,
  ) where

import Control.Monad.Random
import Data.Functor.Identity (Identity (..))

-- | Password/Passphrase generation monad parameterized by the type @gen@ of the generator
-- to carry
type Pass gen = PassT gen Identity

-- | Run a generation computation with the given options and initial generator
runPass :: Pass gen a -> gen -> (a, gen)
runPass :: forall gen a. Pass gen a -> gen -> (a, gen)
runPass Pass gen a
action = Identity (a, gen) -> (a, gen)
forall a. Identity a -> a
runIdentity (Identity (a, gen) -> (a, gen))
-> (gen -> Identity (a, gen)) -> gen -> (a, gen)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pass gen a -> gen -> Identity (a, gen)
forall g (m :: * -> *) a. PassT g m a -> g -> m (a, g)
runPassT Pass gen a
action

-- | Evaluate a generation computation with the given options and initial
--   generator, discarding the final generator
evalPass :: Pass gen a -> gen -> a
evalPass :: forall gen a. Pass gen a -> gen -> a
evalPass Pass gen a
action = Identity a -> a
forall a. Identity a -> a
runIdentity (Identity a -> a) -> (gen -> Identity a) -> gen -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pass gen a -> gen -> Identity a
forall (m :: * -> *) g a. Monad m => PassT g m a -> g -> m a
evalPassT Pass gen a
action

-- | Shorter and more readable alias for @flip runPassT@.
usingPass :: gen -> Pass gen a -> (a, gen)
usingPass :: forall gen a. gen -> Pass gen a -> (a, gen)
usingPass = (Pass gen a -> gen -> (a, gen)) -> gen -> Pass gen a -> (a, gen)
forall a b c. (a -> b -> c) -> b -> a -> c
flip Pass gen a -> gen -> (a, gen)
forall gen a. Pass gen a -> gen -> (a, gen)
runPass

-- | Password/Passphrase generation transformer monad parameterized by :
--
--    * @gen@ - the generator.
--    * @m@ - the inner monad.
newtype PassT gen m a = PassT {forall gen (m :: * -> *) a. PassT gen m a -> RandT gen m a
unPass :: RandT gen m a}
  deriving newtype
    ( Functor (PassT gen m)
Functor (PassT gen m) =>
(forall a. a -> PassT gen m a)
-> (forall a b.
    PassT gen m (a -> b) -> PassT gen m a -> PassT gen m b)
-> (forall a b c.
    (a -> b -> c) -> PassT gen m a -> PassT gen m b -> PassT gen m c)
-> (forall a b. PassT gen m a -> PassT gen m b -> PassT gen m b)
-> (forall a b. PassT gen m a -> PassT gen m b -> PassT gen m a)
-> Applicative (PassT gen m)
forall a. a -> PassT gen m a
forall a b. PassT gen m a -> PassT gen m b -> PassT gen m a
forall a b. PassT gen m a -> PassT gen m b -> PassT gen m b
forall a b. PassT gen m (a -> b) -> PassT gen m a -> PassT gen m b
forall a b c.
(a -> b -> c) -> PassT gen m a -> PassT gen m b -> PassT gen m c
forall gen (m :: * -> *). Monad m => Functor (PassT gen m)
forall gen (m :: * -> *) a. Monad m => a -> PassT gen m a
forall gen (m :: * -> *) a b.
Monad m =>
PassT gen m a -> PassT gen m b -> PassT gen m a
forall gen (m :: * -> *) a b.
Monad m =>
PassT gen m a -> PassT gen m b -> PassT gen m b
forall gen (m :: * -> *) a b.
Monad m =>
PassT gen m (a -> b) -> PassT gen m a -> PassT gen m b
forall gen (m :: * -> *) a b c.
Monad m =>
(a -> b -> c) -> PassT gen m a -> PassT gen m b -> PassT gen m c
forall (f :: * -> *).
Functor f =>
(forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
$cpure :: forall gen (m :: * -> *) a. Monad m => a -> PassT gen m a
pure :: forall a. a -> PassT gen m a
$c<*> :: forall gen (m :: * -> *) a b.
Monad m =>
PassT gen m (a -> b) -> PassT gen m a -> PassT gen m b
<*> :: forall a b. PassT gen m (a -> b) -> PassT gen m a -> PassT gen m b
$cliftA2 :: forall gen (m :: * -> *) a b c.
Monad m =>
(a -> b -> c) -> PassT gen m a -> PassT gen m b -> PassT gen m c
liftA2 :: forall a b c.
(a -> b -> c) -> PassT gen m a -> PassT gen m b -> PassT gen m c
$c*> :: forall gen (m :: * -> *) a b.
Monad m =>
PassT gen m a -> PassT gen m b -> PassT gen m b
*> :: forall a b. PassT gen m a -> PassT gen m b -> PassT gen m b
$c<* :: forall gen (m :: * -> *) a b.
Monad m =>
PassT gen m a -> PassT gen m b -> PassT gen m a
<* :: forall a b. PassT gen m a -> PassT gen m b -> PassT gen m a
Applicative,
      (forall a b. (a -> b) -> PassT gen m a -> PassT gen m b)
-> (forall a b. a -> PassT gen m b -> PassT gen m a)
-> Functor (PassT gen m)
forall a b. a -> PassT gen m b -> PassT gen m a
forall a b. (a -> b) -> PassT gen m a -> PassT gen m b
forall gen (m :: * -> *) a b.
Functor m =>
a -> PassT gen m b -> PassT gen m a
forall gen (m :: * -> *) a b.
Functor m =>
(a -> b) -> PassT gen m a -> PassT gen m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall gen (m :: * -> *) a b.
Functor m =>
(a -> b) -> PassT gen m a -> PassT gen m b
fmap :: forall a b. (a -> b) -> PassT gen m a -> PassT gen m b
$c<$ :: forall gen (m :: * -> *) a b.
Functor m =>
a -> PassT gen m b -> PassT gen m a
<$ :: forall a b. a -> PassT gen m b -> PassT gen m a
Functor,
      Applicative (PassT gen m)
Applicative (PassT gen m) =>
(forall a b.
 PassT gen m a -> (a -> PassT gen m b) -> PassT gen m b)
-> (forall a b. PassT gen m a -> PassT gen m b -> PassT gen m b)
-> (forall a. a -> PassT gen m a)
-> Monad (PassT gen m)
forall a. a -> PassT gen m a
forall a b. PassT gen m a -> PassT gen m b -> PassT gen m b
forall a b. PassT gen m a -> (a -> PassT gen m b) -> PassT gen m b
forall gen (m :: * -> *). Monad m => Applicative (PassT gen m)
forall gen (m :: * -> *) a. Monad m => a -> PassT gen m a
forall gen (m :: * -> *) a b.
Monad m =>
PassT gen m a -> PassT gen m b -> PassT gen m b
forall gen (m :: * -> *) a b.
Monad m =>
PassT gen m a -> (a -> PassT gen m b) -> PassT gen m b
forall (m :: * -> *).
Applicative m =>
(forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
$c>>= :: forall gen (m :: * -> *) a b.
Monad m =>
PassT gen m a -> (a -> PassT gen m b) -> PassT gen m b
>>= :: forall a b. PassT gen m a -> (a -> PassT gen m b) -> PassT gen m b
$c>> :: forall gen (m :: * -> *) a b.
Monad m =>
PassT gen m a -> PassT gen m b -> PassT gen m b
>> :: forall a b. PassT gen m a -> PassT gen m b -> PassT gen m b
$creturn :: forall gen (m :: * -> *) a. Monad m => a -> PassT gen m a
return :: forall a. a -> PassT gen m a
Monad,
      Monad (PassT gen m)
Monad (PassT gen m) =>
(forall a. String -> PassT gen m a) -> MonadFail (PassT gen m)
forall a. String -> PassT gen m a
forall gen (m :: * -> *). MonadFail m => Monad (PassT gen m)
forall gen (m :: * -> *) a. MonadFail m => String -> PassT gen m a
forall (m :: * -> *).
Monad m =>
(forall a. String -> m a) -> MonadFail m
$cfail :: forall gen (m :: * -> *) a. MonadFail m => String -> PassT gen m a
fail :: forall a. String -> PassT gen m a
MonadFail,
      Monad (PassT gen m)
Monad (PassT gen m) =>
(forall a. Random a => (a, a) -> PassT gen m a)
-> (forall a. Random a => PassT gen m a)
-> (forall a. Random a => (a, a) -> PassT gen m [a])
-> (forall a. Random a => PassT gen m [a])
-> MonadRandom (PassT gen m)
forall a. Random a => PassT gen m a
forall a. Random a => PassT gen m [a]
forall a. Random a => (a, a) -> PassT gen m a
forall a. Random a => (a, a) -> PassT gen m [a]
forall gen (m :: * -> *).
(RandomGen gen, Monad m) =>
Monad (PassT gen m)
forall gen (m :: * -> *) a.
(RandomGen gen, Monad m, Random a) =>
PassT gen m a
forall gen (m :: * -> *) a.
(RandomGen gen, Monad m, Random a) =>
PassT gen m [a]
forall gen (m :: * -> *) a.
(RandomGen gen, Monad m, Random a) =>
(a, a) -> PassT gen m a
forall gen (m :: * -> *) a.
(RandomGen gen, Monad m, Random a) =>
(a, a) -> PassT gen m [a]
forall (m :: * -> *).
Monad m =>
(forall a. Random a => (a, a) -> m a)
-> (forall a. Random a => m a)
-> (forall a. Random a => (a, a) -> m [a])
-> (forall a. Random a => m [a])
-> MonadRandom m
$cgetRandomR :: forall gen (m :: * -> *) a.
(RandomGen gen, Monad m, Random a) =>
(a, a) -> PassT gen m a
getRandomR :: forall a. Random a => (a, a) -> PassT gen m a
$cgetRandom :: forall gen (m :: * -> *) a.
(RandomGen gen, Monad m, Random a) =>
PassT gen m a
getRandom :: forall a. Random a => PassT gen m a
$cgetRandomRs :: forall gen (m :: * -> *) a.
(RandomGen gen, Monad m, Random a) =>
(a, a) -> PassT gen m [a]
getRandomRs :: forall a. Random a => (a, a) -> PassT gen m [a]
$cgetRandoms :: forall gen (m :: * -> *) a.
(RandomGen gen, Monad m, Random a) =>
PassT gen m [a]
getRandoms :: forall a. Random a => PassT gen m [a]
MonadRandom,
      Monad (PassT gen m)
Monad (PassT gen m) =>
(forall a. IO a -> PassT gen m a) -> MonadIO (PassT gen m)
forall a. IO a -> PassT gen m a
forall gen (m :: * -> *). MonadIO m => Monad (PassT gen m)
forall gen (m :: * -> *) a. MonadIO m => IO a -> PassT gen m a
forall (m :: * -> *).
Monad m =>
(forall a. IO a -> m a) -> MonadIO m
$cliftIO :: forall gen (m :: * -> *) a. MonadIO m => IO a -> PassT gen m a
liftIO :: forall a. IO a -> PassT gen m a
MonadIO
    )

-- | Run a generation computation with the given options and initial generator
runPassT :: PassT g m a -> g -> m (a, g)
runPassT :: forall g (m :: * -> *) a. PassT g m a -> g -> m (a, g)
runPassT = RandT g m a -> g -> m (a, g)
forall g (m :: * -> *) a. RandT g m a -> g -> m (a, g)
runRandT (RandT g m a -> g -> m (a, g))
-> (PassT g m a -> RandT g m a) -> PassT g m a -> g -> m (a, g)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PassT g m a -> RandT g m a
forall gen (m :: * -> *) a. PassT gen m a -> RandT gen m a
unPass

-- | Evaluate a generation computation with the given options and initial
--   generator, discarding the final generator
evalPassT :: Monad m => PassT g m a -> g -> m a
evalPassT :: forall (m :: * -> *) g a. Monad m => PassT g m a -> g -> m a
evalPassT = RandT g m a -> g -> m a
forall (m :: * -> *) g a. Monad m => RandT g m a -> g -> m a
evalRandT (RandT g m a -> g -> m a)
-> (PassT g m a -> RandT g m a) -> PassT g m a -> g -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PassT g m a -> RandT g m a
forall gen (m :: * -> *) a. PassT gen m a -> RandT gen m a
unPass

-- | Shorter and more readable alias for @flip runPassT@.
usingPassT :: g -> PassT g m a -> m (a, g)
usingPassT :: forall g (m :: * -> *) a. g -> PassT g m a -> m (a, g)
usingPassT = (PassT g m a -> g -> m (a, g)) -> g -> PassT g m a -> m (a, g)
forall a b c. (a -> b -> c) -> b -> a -> c
flip PassT g m a -> g -> m (a, g)
forall g (m :: * -> *) a. PassT g m a -> g -> m (a, g)
runPassT