{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE RankNTypes #-} {-| Optic counterparts of MonadReader combinators from the lens library. |-} module Control.Lens.HReader ( hreader , hasks , hview , hviews , hiview , hperform , hperforml ) where import Control.Comonad import Control.Lens import Control.Lens.Action.Internal import Control.Lens.Action.Type import Control.Monad.HReader import Data.HSet import Data.Profunctor.Rep import Data.Profunctor.Sieve hreader :: (MonadHReader m, HGettable (MHRElements m) s) => (s -> a) -> m a hreader f = do e <- hask return $ f e hasks :: (MonadHReader m, HGettable (MHRElements m) s) => (s -> a) -> m a hasks = hreader hview :: (MonadHReader m, HGettable (MHRElements m) s) => Getting a s a -> m a hview l = hasks (getConst . l Const) {-# INLINE hview #-} hviews :: (MonadHReader m, HGettable (MHRElements m) s) => LensLike' (Const r) s a -> (a -> r) -> m r hviews l f = hasks (getConst . l (Const . f)) {-# INLINE hviews #-} hiview :: (MonadHReader m, HGettable (MHRElements m) s) => IndexedGetting i (i,a) s a -> m (i,a) hiview l = hasks (getConst . l (Indexed $ \i -> Const . (,) i)) {-# INLINE hiview #-} -- | It actually semantically similar to a mix of hask and @act@, performing -- the monadic action on @s@ taken from the optic composition on the left and @r@ -- from HReader on the right. -- @ -- -- type A = Int -- type B = Int -- -- data R = R { _baz :: B } -- -- makeLenses ''R -- -- foo :: IO Int -- foo = runHReaderT (HSCons (3::A) HSNil) f -- where -- f :: HReaderT '[Int] IO B -- f = R 3 ^! baz . hperform g . baz -- g :: B -> A -> HReaderT '[Int] IO R -- g = \x y -> pure (R (x * y)) -- @ -- hperform :: (MonadHReader m, HGettable (MHRElements m) r) => (s -> r -> m a) -> IndexPreservingAction m s a hperform srma pafb = cotabulate $ \ws -> effective $ do a <- srma (extract ws) =<< hask ineffective (cosieve pafb (a <$ ws)) {-# INLINE hperform #-} -- | Flipped version of 'hperform' hperforml :: (MonadHReader m, HGettable (MHRElements m) r) => (r -> s -> m a) -> IndexPreservingAction m s a hperforml rsma pafb = cotabulate $ \ws -> effective $ do a <- flip rsma (extract ws) =<< hask ineffective (cosieve pafb (a <$ ws)) {-# INLINE hperforml #-}