{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE Safe #-}
module Control.Eff.Reader.Strict ( Reader (..)
, ask
, local
, reader
, runReader
) where
import Control.Eff.Internal
import Data.OpenUnion
import Control.Monad.Base
import Control.Monad.Trans.Control
data Reader e v where
Ask :: Reader e e
ask :: (Member (Reader e) r) => Eff r e
ask = send Ask
runReader :: e -> Eff (Reader e ': r) w -> Eff r w
runReader !e = handle_relay
return
(\Ask -> ($ e))
local :: forall e a r. Member (Reader e) r =>
(e -> e) -> Eff r a -> Eff r a
local f m = do
e <- reader f
let
h :: Reader e t -> (t -> Eff r b) -> Eff r b
h Ask = ($ e)
interpose return h m
reader :: (Member (Reader e) r) => (e -> a) -> Eff r a
reader f = f `fmap` ask
instance ( MonadBase m m
, SetMember Lift (Lift m) s
, MonadBaseControl m (Eff s)
) => MonadBaseControl m (Eff (Reader e ': s)) where
type StM (Eff (Reader e ': s)) a = StM (Eff s) a
liftBaseWith f = do !e <- ask
raise $ liftBaseWith $ \runInBase ->
f (runInBase . runReader e)
restoreM = raise . restoreM