diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+0.2.1.0
+=======
+
+  * Add a `shouldPerform` expectation
+  * Improve expectations' error messages
+
 0.2.0.0
 =======
 
diff --git a/README.lhs b/README.lhs
new file mode 100644
--- /dev/null
+++ b/README.lhs
@@ -0,0 +1,144 @@
+hspec-expectations-lens
+=======================
+[![Hackage](https://budueba.com/hackage/hspec-expectations-lens)](http://hackage.haskell.org/package/hspec-expectations-lens)
+[![Build Status](https://secure.travis-ci.org/supki/hspec-expectations-lens.png?branch=master)](http://travis-ci.org/supki/hspec-expectations-lens)
+
+hspec-expectations-lens is a set of expectations for [Hspec][hspec]
+with a [lens][lens]-compatible interface
+
+This README is a literate haskell file which contains a Hspec spec.
+You can run it with `runhaskell`; result is something akin to:
+
+
+```shell
+% runhaskell README.lhs
+
+shouldHave
+  - checks targets exist
+  - looks as deep into structure as you want
+  - replaces 'shouldBe'
+  - checks a bigger part of the structure for equality
+  - checks the whole structure for equality
+
+shouldNotHave
+  - is the opposite of 'shouldHave'
+
+shouldView
+  - gets a single target verbatim
+  - combines multiple targets using Monoid instance
+
+shouldList
+  - combines multiple targets into list
+
+shouldPreview
+  - gets the first target
+
+shouldPerform
+  - performs an action and gets the first target
+
+shouldThrow
+  - looks into the 'error' call
+  - looks into the division by zero
+```
+
+Expectations
+------------
+
+We start with pragmas, module declaration, and imports we use later.
+
+> {-# LANGUAGE ExtendedDefaultRules #-} -- this is only neccessary because we don't like annotations
+>
+> module Main (main) where
+>
+> import Control.Lens
+> import Data.List.Lens
+> import Control.Exception (evaluate)
+> import Control.Exception.Lens (_ErrorCall, _DivideByZero)
+> import Test.Hspec.Lens
+>
+> main :: IO ()
+> main = hspec $ do
+
+hspec-expectations-lens expectations form several groups. First one contains `shouldHave`
+and `shouldNotHave` combinators—they check whether a `Fold` you give them has (or doesn't have)
+any targets in the structure.
+
+>   describe "shouldHave" $ do
+>     it "checks targets exist" $
+>       Right (Just (Left 'a')) `shouldHave` _Right
+
+We can look arbitrarily deep into the structure; for instance, `_Right._Just._Left`
+would also work here:
+
+>     it "looks as deep into structure as you want" $
+>       Right (Just (Left 'a')) `shouldHave` _Right._Just
+
+Finally, `shouldHave` can happily be used as a replacement for a vanilla `shouldBe`.
+
+>     it "replaces 'shouldBe'" $
+>       Right (Just (Left 'a')) `shouldHave` _Right._Just._Left.only 'a'
+>
+>     it "checks a bigger part of the structure for equality" $
+>       Right (Just (Left 'a')) `shouldHave` _Right._Just.only (Left 'a')
+>
+>     it "checks the whole structure for equality" $
+>       Right (Just (Left 'a')) `shouldHave` only (Right (Just (Left 'a')))
+
+`shouldNotHave` is the opposite of `shouldHave` as its name implies, it checks
+whether a `Fold` does not have any targets in the structure.
+
+>   describe "shouldNotHave" $
+>     it "is the opposite of 'shouldHave'" $
+>       Right (Just (Left 'a')) `shouldNotHave` _Left
+
+Next group of expectations is those of them that actually care about the result
+of looking into the structure.  It consists of `shouldView`, `shouldPreview`,
+`shouldList`, and `shouldPerform`.  They derive names from `view`, `preview`, `toListOf`,
+and `perform` `combinators from the lens package.
+
+`shouldView` works similarly to `view`, no big surprises here. If a `Fold` is actually
+a `Getter`, you just get its target:
+
+>   describe "shouldView" $ do
+>     it "gets a single target verbatim" $
+>       (1, (((1, 7), 8), 2, (3, 4), 5, 7)) `shouldView` 7 `through` _2._1._1._2
+
+(`through` is just a fancy name for `id`; it helps to avoid parentheses)
+
+Otherwise, if `Fold` has multiple targets, they are combined using `Monoid` instance
+for the target type (and it better have one):
+
+>     it "combines multiple targets using Monoid instance" $
+>       [("foo", 1), ("bar", 2), ("baz", 3)] `shouldView` "foobarbaz" `through` folded._1
+
+`shouldList` is like `toListOf`, that is, it combines its targets into the list:
+
+>   describe "shouldList" $
+>     it "combines multiple targets into list" $
+>       [("foo", 1), ("bar", 2), ("baz", 3)] `shouldList` [1, 2, 3] `through` folded._2
+
+`shouldPreview` is like `preview` in that it only cares about the first target:
+
+>   describe "shouldPreview" $
+>     it "gets the first target" $
+>       [1..10] `shouldPreview` 10 `through` reversed.folded
+
+`shouldPerform` performs the action and looks into the first target of the result.
+
+>   describe "shouldPerform" $
+>     it "performs an action and gets the first target" $
+>       readFile "README.lhs" `shouldPerform` 99 `through` to lines.folded.prefixed ">".to length
+
+The last combinator, which does not really belong to any of the previous groups,
+is `shouldThrow`. It uses composable selectors to determine which
+exception was thrown:
+
+>   describe "shouldThrow" $ do
+>     it "looks into the 'error' call" $
+>       error "foo" `shouldThrow` _ErrorCall.only "foo"
+>
+>     it "looks into the division by zero" $
+>       evaluate (1 `div` 0) `shouldThrow` _DivideByZero
+
+  [hspec]: http://hspec.github.io/
+  [lens]: https://github.com/ekmett/lens/
diff --git a/README.md b/README.md
deleted file mode 100644
--- a/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-hspec-expectations-lens
-======
-[![Hackage](https://budueba.com/hackage/hspec-expectations-lens)](http://hackage.haskell.org/package/hspec-expectations-lens)
-[![Build Status](https://secure.travis-ci.org/supki/hspec-expectations-lens.png?branch=master)](http://travis-ci.org/supki/hspec-expectations-lens)
-
-Hspec expectations for the lens stuff
diff --git a/hspec-expectations-lens.cabal b/hspec-expectations-lens.cabal
--- a/hspec-expectations-lens.cabal
+++ b/hspec-expectations-lens.cabal
@@ -1,5 +1,5 @@
 name:                hspec-expectations-lens
-version:             0.2.0.0
+version:             0.2.1.0
 synopsis:            Hspec expectations for the lens stuff
 description:
   Package adds hspec expectations (@\`shouldX\`@ things)
@@ -13,7 +13,7 @@
 build-type:          Simple
 extra-source-files:
   CHANGELOG.md
-  README.md
+  README.lhs
 cabal-version:       >= 1.10
 
 source-repository head
@@ -22,7 +22,7 @@
 
 source-repository this
   type:     git
-  tag:      0.2.0.0
+  tag:      0.2.1.0
   location: https://github.com/supki/hspec-expectations-lens
 
 library
diff --git a/src/Test/Hspec/Expectations/Lens.hs b/src/Test/Hspec/Expectations/Lens.hs
--- a/src/Test/Hspec/Expectations/Lens.hs
+++ b/src/Test/Hspec/Expectations/Lens.hs
@@ -7,10 +7,12 @@
   , shouldPreview
   , shouldList
   , shouldThrow
+  , shouldPerform
   , through
   ) where
 
 import Control.Lens
+import Control.Monad
 import Control.Exception (SomeException)
 import Control.Exception.Lens
 import Data.Monoid (Any(..), All(..), First(..), Endo(..))
@@ -19,11 +21,17 @@
 import Text.Printf (printf)
 
 
-infixl 1 `shouldHave`, `shouldNotHave`, `shouldView`, `shouldPreview`, `shouldList`, `shouldThrow`, `through`
+infixl 1 `shouldHave`, `shouldNotHave`
+infixl 1 `shouldView`, `shouldPreview`, `shouldList`
+infixl 1 `shouldThrow`
+infixl 1 `shouldPerform`
+infixl 1 `through`
 
--- | @x \`shouldHave\` l@ sets the expectation that 'Fold' @l@ has
--- non-zero number of targets in @x@
+-- | @s \`shouldHave\` l@ sets the expectation that 'Fold' @l@ has
+-- non-zero number of targets in the structure @s@
 --
+-- > s `shouldBe` t ≡ s `shouldHave` only t
+--
 -- @
 -- shouldHave :: 'Show' s => s -> 'Getter'     s a -> 'Expectation'
 -- shouldHave :: 'Show' s => s -> 'Fold'       s a -> 'Expectation'
@@ -33,12 +41,12 @@
 -- shouldHave :: 'Show' s => s -> 'Prism''     s a -> 'Expectation'
 -- @
 shouldHave :: Show s => s -> Getting Any s a -> Expectation
-x `shouldHave` f = assertBool msg (has f x)
+s `shouldHave` l = assertBool msg (has l s)
  where
-  msg = printf "Supplied Fold has zero targets for %s" (show x)
+  msg = printf "This Fold has zero targets for %s" (show s)
 
--- | @x \`shouldNotHave\` l@ sets the expectation that 'Fold' @l@
--- has zero targets in @x@
+-- | @s \`shouldNotHave\` l@ sets the expectation that 'Fold' @l@
+-- has exactly zero targets in the structue @s@
 --
 -- @
 -- shouldNotHave :: 'Show' s => s -> 'Getter'     s a -> 'Expectation'
@@ -49,12 +57,12 @@
 -- shouldNotHave :: 'Show' s => s -> 'Prism''     s a -> 'Expectation'
 -- @
 shouldNotHave :: Show s => s -> Getting All s a -> Expectation
-x `shouldNotHave` f = assertBool msg (hasn't f x)
+s `shouldNotHave` l = assertBool msg (hasn't l s)
  where
-  msg = printf "Supplied Fold has non-zero targets for %s" (show x)
+  msg = printf "This Fold has non-zero targets for %s" (show s)
 
--- | @x \`shouldView\` y \`through\` l@ sets the expectation that
--- you can see @y@ in @x@ though a 'Getter' @l@
+-- | @s \`shouldView\` t \`through\` l@ sets the expectation that
+-- you can see target @t@ in the structure @s@ though a 'Getter' @l@
 --
 -- @
 -- shouldView ::           ('Show' s, 'Show' a, 'Eq' a) => s -> a -> 'Getter'     s a -> 'Expectation'
@@ -65,12 +73,13 @@
 -- shouldView :: ('Data.Monoid.Monoid' m, 'Show' s, 'Show' a, 'Eq' a) => s -> a -> 'Prism''     s m -> 'Expectation'
 -- @
 shouldView :: (Show s, Show a, Eq a) => s -> a -> Getting a s a -> Expectation
-(x `shouldView` y) l = assertBool msg (view l x == y)
- where
-  msg = printf "Can't view %s from %s through supplied Getter" (show y) (show x)
+(s `shouldView` t) l =
+  let r = view l s in
+    unless (r == t) $
+      assertFailure (printf "Resulted in %s, but expected %s" (show r) (show t))
 
--- | @x \`shouldPreview\` y \`through\` l@ sets the expectation that
--- you can list @y@ in @x@ first though a 'Fold' @l@
+-- | @s \`shouldPreview\` t \`through\` l@ sets the expectation that
+-- you @y@ is the first target of the 'Fold' @l@ in @s@
 --
 -- @
 -- shouldPreview :: ('Show' s, 'Show' a, 'Eq' a) => s -> a -> 'Getter'     s a -> 'Expectation'
@@ -81,12 +90,15 @@
 -- shouldPreview :: ('Show' s, 'Show' a, 'Eq' a) => s -> a -> 'Prism''     s a -> 'Expectation'
 -- @
 shouldPreview :: (Show s, Show a, Eq a) => s -> a -> Getting (First a) s a -> Expectation
-(x `shouldPreview` y) l = assertBool msg (preview l x == Just y)
- where
-  msg = printf "Can't preview %s from %s through supplied Fold" (show y) (show x)
+(s `shouldPreview` t) l =
+  case preview l s of
+    Nothing ->
+      assertFailure (printf "No targets, but expected %s" (show t))
+    Just r  -> unless (r == t) $
+      assertFailure (printf "Resulted in %s, but expected %s" (show r) (show t))
 
--- | @x \`shouldList\` ys \`through\` l@ sets the expectation that
--- you can list @ys@ in @x@ though a 'Fold' @l@
+-- | @s \`shouldList\` ts \`through\` l@ sets the expectation that
+-- @ts@ is a list of the Fold @l@ targets in @x@
 --
 -- @
 -- shouldList :: ('Show' s, 'Show' a, 'Eq' a) => s -> [a] -> 'Getter'     s a -> 'Expectation'
@@ -97,29 +109,47 @@
 -- shouldList :: ('Show' s, 'Show' a, 'Eq' a) => s -> [a] -> 'Prism''     s a -> 'Expectation'
 -- @
 shouldList :: (Show s, Show a, Eq a) => s -> [a] -> Getting (Endo [a]) s a -> Expectation
-(x `shouldList` y) l = assertBool msg (toListOf l x == y)
- where
-  msg = printf "Can't list %s from %s through supplied Fold" (show y) (show x)
+(s `shouldList` t) l =
+  let r = toListOf l s in
+    unless (r == t) $
+      assertFailure (printf "Resulted in %s, but expected %s" (show r) (show t))
 
--- | @x \`shouldthrow\` l@ sets the expectation that
--- @x@ throws an exception catchable with a 'Fold' @l@
+-- | @a \`shouldThrow\` l@ sets the expectation that
+-- @a@ throws an exception that 'Fold' @l@ can catch
 --
--- /Note:/ name conflicts with 'Test.Hspec.Expectations.shouldThrow'
+-- "Test.Hspec" exports 'Test.Hspec.Expectations.shouldThrow' too; it
+-- only allows @e -> Bool@ selectors, which is less general and often less convenient
 --
 -- @
--- shouldThrow :: 'IO' a -> -> 'Getter'     s b -> 'Expectation'
--- shouldThrow :: 'IO' a -> -> 'Fold'       s b -> 'Expectation'
--- shouldThrow :: 'IO' a -> -> 'Lens''      s b -> 'Expectation'
--- shouldThrow :: 'IO' a -> -> 'Iso''       s b -> 'Expectation'
--- shouldThrow :: 'IO' a -> -> 'Traversal'' s b -> 'Expectation'
--- shouldThrow :: 'IO' a -> -> 'Prism''     s b -> 'Expectation'
+-- shouldThrow :: 'IO' a -> 'Getter'     s b -> 'Expectation'
+-- shouldThrow :: 'IO' a -> 'Fold'       s b -> 'Expectation'
+-- shouldThrow :: 'IO' a -> 'Lens''      s b -> 'Expectation'
+-- shouldThrow :: 'IO' a -> 'Iso''       s b -> 'Expectation'
+-- shouldThrow :: 'IO' a -> 'Traversal'' s b -> 'Expectation'
+-- shouldThrow :: 'IO' a -> 'Prism''     s b -> 'Expectation'
 -- @
 shouldThrow :: IO a -> Getting (First b) SomeException b -> Expectation
 x `shouldThrow` l = do
   r <- trying l x
   case r of
     Left  _ -> return ()
-    Right _ -> assertFailure "Couldn't catch any exceptions with the supplied Fold"
+    Right _ -> assertFailure "Couldn't catch any exceptions"
+
+-- | @a \`shouldPerform\` t \`through\` l@ sets the expectation that @t@ is
+-- a target of the 'MonadicFold' @l@ applied to the result of action @a@
+--
+-- @
+-- shouldPerform :: ('Show' a, 'Eq' a) => 'IO' s -> a -> 'Action'      'IO' s a -> 'Expectation'
+-- shouldPerform :: ('Show' a, 'Eq' a) => 'IO' s -> a -> 'MonadicFold' 'IO' s a -> 'Expectation'
+-- @
+shouldPerform :: (Show a, Eq a) => IO s -> a -> Acting IO (Leftmost a) s s a b -> Expectation
+(x `shouldPerform` t) l = do
+  r <- x ^!? acts.l
+  case r of
+    Nothing ->
+      assertFailure (printf "No targets, but expected %s" (show t))
+    Just r' -> unless (r' == t) $
+      assertFailure (printf "Resulted in %s, but expected %s" (show r') (show t))
 
 -- | A helper to fight parentheses
 --
