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

import Prelude.Compat

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 { SupplyT m a -> StateT Integer m a
unSupplyT :: StateT Integer m a }
  deriving (a -> SupplyT m b -> SupplyT m a
(a -> b) -> SupplyT m a -> SupplyT m b
(forall a b. (a -> b) -> SupplyT m a -> SupplyT m b)
-> (forall a b. a -> SupplyT m b -> SupplyT m a)
-> Functor (SupplyT m)
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
<$ :: a -> SupplyT m b -> SupplyT m a
$c<$ :: forall (m :: * -> *) a b.
Functor m =>
a -> SupplyT m b -> SupplyT m a
fmap :: (a -> b) -> SupplyT m a -> SupplyT m b
$cfmap :: forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> SupplyT m a -> SupplyT m b
Functor, Functor (SupplyT m)
a -> SupplyT m a
Functor (SupplyT m)
-> (forall a. a -> SupplyT m a)
-> (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 a b. SupplyT m a -> SupplyT m b -> SupplyT m b)
-> (forall a b. SupplyT m a -> SupplyT m b -> SupplyT m a)
-> Applicative (SupplyT m)
SupplyT m a -> SupplyT m b -> SupplyT m b
SupplyT m a -> SupplyT m b -> SupplyT m a
SupplyT m (a -> b) -> SupplyT m a -> SupplyT m b
(a -> b -> c) -> SupplyT m a -> SupplyT m b -> SupplyT m c
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
<* :: 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
*> :: 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 :: (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
<*> :: 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 :: a -> SupplyT m a
$cpure :: forall (m :: * -> *) a. Monad m => a -> SupplyT m a
$cp1Applicative :: forall (m :: * -> *). Monad m => Functor (SupplyT m)
Applicative, Applicative (SupplyT m)
a -> SupplyT m a
Applicative (SupplyT m)
-> (forall a b. SupplyT m a -> (a -> SupplyT m b) -> SupplyT m b)
-> (forall a b. SupplyT m a -> SupplyT m b -> SupplyT m b)
-> (forall a. a -> SupplyT m a)
-> Monad (SupplyT m)
SupplyT m a -> (a -> SupplyT m b) -> SupplyT m b
SupplyT m a -> SupplyT m b -> SupplyT m b
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 :: a -> SupplyT m a
$creturn :: forall (m :: * -> *) a. Monad m => a -> SupplyT m a
>> :: 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
>>= :: 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
$cp1Monad :: forall (m :: * -> *). Monad m => Applicative (SupplyT m)
Monad, m a -> SupplyT m a
(forall (m :: * -> *) a. Monad m => m a -> SupplyT m a)
-> MonadTrans SupplyT
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 :: m a -> SupplyT m a
$clift :: forall (m :: * -> *) a. Monad m => m a -> SupplyT m a
MonadTrans, MonadError e, MonadWriter w, MonadReader r, Applicative (SupplyT m)
SupplyT m a
Applicative (SupplyT m)
-> (forall a. SupplyT m a)
-> (forall a. SupplyT m a -> SupplyT m a -> SupplyT m a)
-> (forall a. SupplyT m a -> SupplyT m [a])
-> (forall a. SupplyT m a -> SupplyT m [a])
-> Alternative (SupplyT m)
SupplyT m a -> SupplyT m a -> SupplyT m a
SupplyT m a -> SupplyT m [a]
SupplyT m a -> SupplyT m [a]
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 :: SupplyT m a -> SupplyT m [a]
$cmany :: forall (m :: * -> *) a. MonadPlus m => SupplyT m a -> SupplyT m [a]
some :: SupplyT m a -> SupplyT m [a]
$csome :: forall (m :: * -> *) a. MonadPlus m => SupplyT m a -> SupplyT m [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 :: SupplyT m a
$cempty :: forall (m :: * -> *) a. MonadPlus m => SupplyT m a
$cp1Alternative :: forall (m :: * -> *). MonadPlus m => Applicative (SupplyT m)
Alternative, Monad (SupplyT m)
Alternative (SupplyT m)
SupplyT m a
Alternative (SupplyT m)
-> Monad (SupplyT m)
-> (forall a. SupplyT m a)
-> (forall a. SupplyT m a -> SupplyT m a -> SupplyT m a)
-> MonadPlus (SupplyT m)
SupplyT m a -> SupplyT m a -> SupplyT m a
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 :: 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 :: SupplyT m a
$cmzero :: forall (m :: * -> *) a. MonadPlus m => SupplyT m a
$cp2MonadPlus :: forall (m :: * -> *). MonadPlus m => Monad (SupplyT m)
$cp1MonadPlus :: forall (m :: * -> *). MonadPlus m => Alternative (SupplyT m)
MonadPlus)

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

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

type Supply = SupplyT Identity

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

evalSupply :: Integer -> Supply a -> a
evalSupply :: Integer -> Supply a -> a
evalSupply Integer
n = Identity a -> a
forall a. Identity a -> a
runIdentity (Identity a -> a) -> (Supply a -> Identity a) -> Supply a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Supply a -> Identity a
forall (m :: * -> *) a. Functor m => Integer -> SupplyT m a -> m a
evalSupplyT Integer
n