module Control.Monad.Freer.Fresh
( Fresh(..)
, fresh
, runFresh
, evalFresh
) where
import Control.Monad.Freer.Internal (Eff, Member, handleRelayS, send)
data Fresh r where
Fresh :: Fresh Int
fresh :: Member Fresh effs => Eff effs Int
fresh :: Eff effs Int
fresh = Fresh Int -> Eff effs Int
forall (eff :: * -> *) (effs :: [* -> *]) a.
Member eff effs =>
eff a -> Eff effs a
send Fresh Int
Fresh
runFresh :: Int -> Eff (Fresh ': effs) a -> Eff effs (a, Int)
runFresh :: Int -> Eff (Fresh : effs) a -> Eff effs (a, Int)
runFresh Int
s =
Int
-> (Int -> a -> Eff effs (a, Int))
-> (forall v.
Int
-> Fresh v -> (Int -> Arr effs v (a, Int)) -> Eff effs (a, Int))
-> Eff (Fresh : effs) a
-> Eff effs (a, Int)
forall s a (effs :: [* -> *]) b (eff :: * -> *).
s
-> (s -> a -> Eff effs b)
-> (forall v. s -> eff v -> (s -> Arr effs v b) -> Eff effs b)
-> Eff (eff : effs) a
-> Eff effs b
handleRelayS Int
s (\Int
s' a
a -> (a, Int) -> Eff effs (a, Int)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a
a, Int
s')) (\Int
s' Fresh v
Fresh Int -> Arr effs v (a, Int)
k -> (Int -> Arr effs v (a, Int)
k (Int -> Arr effs v (a, Int)) -> Int -> Arr effs v (a, Int)
forall a b. (a -> b) -> a -> b
$! Int
s' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) v
Int
s')
evalFresh :: Int -> Eff (Fresh ': effs) a -> Eff effs a
evalFresh :: Int -> Eff (Fresh : effs) a -> Eff effs a
evalFresh Int
s = ((a, Int) -> a) -> Eff effs (a, Int) -> Eff effs a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a, Int) -> a
forall a b. (a, b) -> a
fst (Eff effs (a, Int) -> Eff effs a)
-> (Eff (Fresh : effs) a -> Eff effs (a, Int))
-> Eff (Fresh : effs) a
-> Eff effs a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Eff (Fresh : effs) a -> Eff effs (a, Int)
forall (effs :: [* -> *]) a.
Int -> Eff (Fresh : effs) a -> Eff effs (a, Int)
runFresh Int
s