-- | -- Module: Control.Monad.Freer.Fresh -- Description: Generation of fresh integers as an effect. -- Copyright: (c) 2016 Allele Dev; 2017 Ixperta Solutions s.r.o.; 2017 Alexis King -- License: BSD3 -- Maintainer: Alexis King -- Stability: experimental -- Portability: GHC specific language extensions. -- -- Composable handler for 'Fresh' effects. This is likely to be of use when -- implementing De Bruijn naming/scopes. -- -- Using as a starting point. module Control.Monad.Freer.Fresh ( Fresh(..) , fresh , runFresh , evalFresh ) where import Control.Monad.Freer.Internal (Eff, Member, handleRelayS, send) -- | Fresh effect model. data Fresh r where Fresh :: Fresh Int -- | Request a fresh effect. fresh :: Member Fresh effs => Eff effs Int fresh = send Fresh -- | Handler for 'Fresh' effects, with an 'Int' for a starting value. The -- return value includes the next fresh value. runFresh :: Int -> Eff (Fresh ': effs) a -> Eff effs (a, Int) runFresh s = handleRelayS s (\s' a -> pure (a, s')) (\s' Fresh k -> (k $! s' + 1) s') -- | Handler for 'Fresh' effects, with an 'Int' for a starting value. Discards -- the next fresh value. evalFresh :: Int -> Eff (Fresh ': effs) a -> Eff effs a evalFresh s = fmap fst . runFresh s