-- |
-- Fresh variable supply
--
module Control.Monad.Supply where

import Prelude

import Control.Applicative
import Control.Monad.Error.Class (MonadError(..))
import Control.Monad.Reader
import Control.Monad.State
import Control.Monad.Writer

import Data.Functor.Identity

newtype SupplyT m a = SupplyT { forall (m :: * -> *) a. SupplyT m a -> StateT Integer m a
unSupplyT :: StateT Integer m a }
  deriving (forall a b. a -> SupplyT m b -> SupplyT m a
forall a b. (a -> b) -> SupplyT m a -> SupplyT m b
forall (m :: * -> *) a b.
Functor m =>
a -> SupplyT m b -> SupplyT m a
forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> SupplyT m a -> SupplyT m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> SupplyT m b -> SupplyT m a
$c<$ :: forall (m :: * -> *) a b.
Functor m =>
a -> SupplyT m b -> SupplyT m a
fmap :: forall a b. (a -> b) -> SupplyT m a -> SupplyT m b
$cfmap :: forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> SupplyT m a -> SupplyT m b
Functor, forall a. a -> SupplyT m a
forall a b. SupplyT m a -> SupplyT m b -> SupplyT m a
forall a b. SupplyT m a -> SupplyT m b -> SupplyT m b
forall a b. SupplyT m (a -> b) -> SupplyT m a -> SupplyT m b
forall a b c.
(a -> b -> c) -> SupplyT m a -> SupplyT m b -> SupplyT m c
forall {m :: * -> *}. Monad m => Functor (SupplyT m)
forall (m :: * -> *) a. Monad m => a -> SupplyT m a
forall (m :: * -> *) a b.
Monad m =>
SupplyT m a -> SupplyT m b -> SupplyT m a
forall (m :: * -> *) a b.
Monad m =>
SupplyT m a -> SupplyT m b -> SupplyT m b
forall (m :: * -> *) a b.
Monad m =>
SupplyT m (a -> b) -> SupplyT m a -> SupplyT m b
forall (m :: * -> *) a b c.
Monad m =>
(a -> b -> c) -> SupplyT m a -> SupplyT m b -> SupplyT 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
<* :: forall a b. SupplyT m a -> SupplyT m b -> SupplyT m a
$c<* :: forall (m :: * -> *) a b.
Monad m =>
SupplyT m a -> SupplyT m b -> SupplyT m a
*> :: forall a b. SupplyT m a -> SupplyT m b -> SupplyT m b
$c*> :: forall (m :: * -> *) a b.
Monad m =>
SupplyT m a -> SupplyT m b -> SupplyT m b
liftA2 :: forall a b c.
(a -> b -> c) -> SupplyT m a -> SupplyT m b -> SupplyT m c
$cliftA2 :: forall (m :: * -> *) a b c.
Monad m =>
(a -> b -> c) -> SupplyT m a -> SupplyT m b -> SupplyT m c
<*> :: forall a b. SupplyT m (a -> b) -> SupplyT m a -> SupplyT m b
$c<*> :: forall (m :: * -> *) a b.
Monad m =>
SupplyT m (a -> b) -> SupplyT m a -> SupplyT m b
pure :: forall a. a -> SupplyT m a
$cpure :: forall (m :: * -> *) a. Monad m => a -> SupplyT m a
Applicative, forall a. a -> SupplyT m a
forall a b. SupplyT m a -> SupplyT m b -> SupplyT m b
forall a b. SupplyT m a -> (a -> SupplyT m b) -> SupplyT m b
forall (m :: * -> *). Monad m => Applicative (SupplyT m)
forall (m :: * -> *) a. Monad m => a -> SupplyT m a
forall (m :: * -> *) a b.
Monad m =>
SupplyT m a -> SupplyT m b -> SupplyT m b
forall (m :: * -> *) a b.
Monad m =>
SupplyT m a -> (a -> SupplyT m b) -> SupplyT 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
return :: forall a. a -> SupplyT m a
$creturn :: forall (m :: * -> *) a. Monad m => a -> SupplyT m a
>> :: forall a b. SupplyT m a -> SupplyT m b -> SupplyT m b
$c>> :: forall (m :: * -> *) a b.
Monad m =>
SupplyT m a -> SupplyT m b -> SupplyT m b
>>= :: forall a b. SupplyT m a -> (a -> SupplyT m b) -> SupplyT m b
$c>>= :: forall (m :: * -> *) a b.
Monad m =>
SupplyT m a -> (a -> SupplyT m b) -> SupplyT m b
Monad, forall (m :: * -> *) a. Monad m => m a -> SupplyT m a
forall (t :: (* -> *) -> * -> *).
(forall (m :: * -> *) a. Monad m => m a -> t m a) -> MonadTrans t
lift :: forall (m :: * -> *) a. Monad m => m a -> SupplyT m a
$clift :: forall (m :: * -> *) a. Monad m => m a -> SupplyT m a
MonadTrans, MonadError e, MonadWriter w, MonadReader r, forall a. SupplyT m a
forall a. SupplyT m a -> SupplyT m [a]
forall a. SupplyT m a -> SupplyT m a -> SupplyT m a
forall (f :: * -> *).
Applicative f
-> (forall a. f a)
-> (forall a. f a -> f a -> f a)
-> (forall a. f a -> f [a])
-> (forall a. f a -> f [a])
-> Alternative f
forall {m :: * -> *}. MonadPlus m => Applicative (SupplyT m)
forall (m :: * -> *) a. MonadPlus m => SupplyT m a
forall (m :: * -> *) a. MonadPlus m => SupplyT m a -> SupplyT m [a]
forall (m :: * -> *) a.
MonadPlus m =>
SupplyT m a -> SupplyT m a -> SupplyT m a
many :: forall a. SupplyT m a -> SupplyT m [a]
$cmany :: forall (m :: * -> *) a. MonadPlus m => SupplyT m a -> SupplyT m [a]
some :: forall a. SupplyT m a -> SupplyT m [a]
$csome :: forall (m :: * -> *) a. MonadPlus m => SupplyT m a -> SupplyT m [a]
<|> :: forall a. SupplyT m a -> SupplyT m a -> SupplyT m a
$c<|> :: forall (m :: * -> *) a.
MonadPlus m =>
SupplyT m a -> SupplyT m a -> SupplyT m a
empty :: forall a. SupplyT m a
$cempty :: forall (m :: * -> *) a. MonadPlus m => SupplyT m a
Alternative, forall a. SupplyT m a
forall a. SupplyT m a -> SupplyT m a -> SupplyT m a
forall (m :: * -> *).
Alternative m
-> Monad m
-> (forall a. m a)
-> (forall a. m a -> m a -> m a)
-> MonadPlus m
forall {m :: * -> *}. MonadPlus m => Monad (SupplyT m)
forall (m :: * -> *). MonadPlus m => Alternative (SupplyT m)
forall (m :: * -> *) a. MonadPlus m => SupplyT m a
forall (m :: * -> *) a.
MonadPlus m =>
SupplyT m a -> SupplyT m a -> SupplyT m a
mplus :: forall a. SupplyT m a -> SupplyT m a -> SupplyT m a
$cmplus :: forall (m :: * -> *) a.
MonadPlus m =>
SupplyT m a -> SupplyT m a -> SupplyT m a
mzero :: forall a. SupplyT m a
$cmzero :: forall (m :: * -> *) a. MonadPlus m => SupplyT m a
MonadPlus)

runSupplyT :: Integer -> SupplyT m a -> m (a, Integer)
runSupplyT :: forall (m :: * -> *) a. Integer -> SupplyT m a -> m (a, Integer)
runSupplyT Integer
n = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
runStateT Integer
n forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. SupplyT m a -> StateT Integer m a
unSupplyT

evalSupplyT :: (Functor m) => Integer -> SupplyT m a -> m a
evalSupplyT :: forall (m :: * -> *) a. Functor m => Integer -> SupplyT m a -> m a
evalSupplyT Integer
n = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> a
fst forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. Integer -> SupplyT m a -> m (a, Integer)
runSupplyT Integer
n

type Supply = SupplyT Identity

runSupply :: Integer -> Supply a -> (a, Integer)
runSupply :: forall a. Integer -> Supply a -> (a, Integer)
runSupply Integer
n = forall a. Identity a -> a
runIdentity forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. Integer -> SupplyT m a -> m (a, Integer)
runSupplyT Integer
n