{-# LANGUAGE TemplateHaskell #-}
module Polysemy.Reader
  ( 
    Reader (..)
    
  , ask
  , asks
  , local
    
  , runReader
    
  , inputToReader
  ) where
import Polysemy
import Polysemy.Input
data Reader i m a where
  Ask   :: Reader i m i
  Local :: (i -> i) -> m a -> Reader i m a
makeSem ''Reader
asks :: forall i j r. Member (Reader i) r => (i -> j) -> Sem r j
asks f = f <$> ask
{-# INLINABLE asks #-}
runReader :: i -> Sem (Reader i ': r) a -> Sem r a
runReader i = interpretH $ \case
  Ask -> pureT i
  Local f m -> do
    mm <- runT m
    raise $ runReader (f i) mm
{-# INLINE runReader #-}
inputToReader :: Member (Reader i) r => Sem (Input i ': r) a -> Sem r a
inputToReader = interpret $ \case
  Input -> ask
{-# INLINE inputToReader #-}