diff --git a/hreader-lens.cabal b/hreader-lens.cabal
--- a/hreader-lens.cabal
+++ b/hreader-lens.cabal
@@ -2,7 +2,7 @@
 -- documentation, see http://haskell.org/cabal/users-guide/
 
 name:                hreader-lens
-version:             0.1.1.0
+version:             0.1.2.0
 synopsis:            Optics for hreader package
 -- description:
 license:             MIT
@@ -22,9 +22,11 @@
   -- other-modules:
   -- other-extensions:
   build-depends:       base >=4.5 && <5
+                     , comonad  >= 5
                      , hreader >= 1.0 && < 1.1
                      , hset >=2.0.0 && <3.0.0
                      , lens >= 4
+                     , lens-action >= 0.2
                      , profunctors
   hs-source-dirs:      src
   default-language:    Haskell2010
diff --git a/src/Control/Lens/HReader.hs b/src/Control/Lens/HReader.hs
--- a/src/Control/Lens/HReader.hs
+++ b/src/Control/Lens/HReader.hs
@@ -1,4 +1,6 @@
 {-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE RankNTypes #-}
 
 {-|
 
@@ -7,10 +9,16 @@
 |-}
 module Control.Lens.HReader 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
@@ -34,3 +42,43 @@
   => 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 #-}
