Skip to content

Instantly share code, notes, and snippets.

@LSLeary
Created June 21, 2023 14:06
Show Gist options
  • Save LSLeary/f1268e8b4fca2c7747baf4536127d38c to your computer and use it in GitHub Desktop.
Save LSLeary/f1268e8b4fca2c7747baf4536127d38c to your computer and use it in GitHub Desktop.
Generate fresh Typeable types.
module Fresh
( Fresh, runFresh, withFresh
) where
import Data.Typeable
import Control.Monad.State (StateT, evalStateT, get, put)
import Control.Monad.Trans (MonadTrans)
data Z
data S n
data SomeTypeable where
SomeTypeable :: (Typeable k, Typeable x) => Proxy (x :: k) -> SomeTypeable
newtype Fresh m a = Fresh (StateT SomeTypeable m a)
deriving (Functor, Applicative, Monad, MonadTrans)
runFresh :: Monad m => Fresh m a -> m a
runFresh (Fresh s) = evalStateT s (SomeTypeable (Proxy :: Proxy Z))
withFresh
:: Monad m
=> (forall k (x :: k). Typeable x => Proxy x -> Fresh m r)
-> Fresh m r
withFresh f = do
SomeTypeable (p :: Proxy n) <- Fresh get
Fresh (put (SomeTypeable (Proxy :: Proxy (S n))))
f p
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment