freer-effects-0.3.0.0: src/Control/Monad/Freer/Fresh.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE TypeOperators #-}
-- |
-- Module: Control.Monad.Freer.Fresh
-- Description: Generation of fresh integers as an effect.
-- Copyright: (c) 2016 Allele Dev; 2017 Ixperta Solutions s.r.o.
-- License: BSD3
-- Maintainer: ixcom-core@ixperta.com
-- Stability: broken
-- Portability: GHC specific language extensions.
--
-- Composable handler for 'Fresh' effects. This is likely to be of use when
-- implementing De Bruijn naming/scopes.
--
-- Using <http://okmij.org/ftp/Haskell/extensible/Eff1.hs> as a starting point.
module Control.Monad.Freer.Fresh
( Fresh(..)
, fresh
, runFresh'
)
where
import Prelude (($!), (+))
import Control.Applicative (pure)
import Data.Int (Int)
import Control.Monad.Freer.Internal (Eff, Member, handleRelayS, send)
--------------------------------------------------------------------------------
-- Fresh --
--------------------------------------------------------------------------------
-- | Fresh effect model.
data Fresh a 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.
runFresh' :: Eff (Fresh ': effs) a -> Int -> Eff effs a
runFresh' m s =
handleRelayS s (\_s a -> pure a) (\s' Fresh k -> (k $! s' + 1) s') m