diff --git a/CHANGES.txt b/CHANGES.txt
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,5 +1,8 @@
 Changelog for HLint
 
+2.0.6
+    Do statements are not redundant if they change an operator parse
+    #333, simplify labels on Parse error, makes it easier to ignore
 2.0.5
     If the datadir is missing use data/ relative to the executable
     Fix test mode to obey --datadir
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -56,6 +56,26 @@
 
 **Bug reports:** The suggested replacement should be equivalent - please report all incorrect suggestions not mentioned as known limitations.
 
+### Running with Continuous Integration
+
+Before running HLint on your continuous integration (CI) server, you should first ensure there are no existing hints. One way to achieve that is to ignore existing hints by running `hlint . --default > .hlint.yaml` and checking in the resulting `.hlint.yaml`.
+
+On the CI you should then run `hlint .` (or `hlint src` if you only want to check the `src` directory). To avoid the cost of compilation you may wish to fetch the [latest HLint binary release](https://github.com/ndmitchell/hlint/releases/latest). For certain CI environments there are helper scripts to do that.
+
+**Travis:** Execute the following command:
+
+    wget https://raw.github.com/ndmitchell/hlint/master/misc/travis.sh -O - --quiet | sh -s .
+
+The arguments after `-s` are passed to `hlint`, so modify the final `.` if you want other arguments.
+
+**Appveyor:** Add the following statements to `.appveyor.yml`:
+
+    - set PATH=C:\Program Files\Git\mingw64\bin;%PATH%
+    - curl -ohlint.bat -L https://raw.githubusercontent.com/ndmitchell/hlint/master/misc/appveyor.bat
+    - hlint .
+
+The `PATH` modification ensures `curl` is available on Appveyor. The final statement executes `hlint.bat` with whatever arguments you desire.
+
 ### Automatically Applying Hints
 
 By supplying the `--refactor` flag hlint can automatically apply most
diff --git a/hlint.cabal b/hlint.cabal
--- a/hlint.cabal
+++ b/hlint.cabal
@@ -1,7 +1,7 @@
 cabal-version:      >= 1.18
 build-type:         Simple
 name:               hlint
-version:            2.0.5
+version:            2.0.6
 license:            BSD3
 license-file:       LICENSE
 category:           Development
diff --git a/src/Apply.hs b/src/Apply.hs
--- a/src/Apply.hs
+++ b/src/Apply.hs
@@ -74,7 +74,7 @@
         Left (ParseError sl msg ctxt) -> do
             i <- return $ rawIdeaN Error "Parse error" (mkSrcSpan sl sl) ctxt Nothing []
             i <- return $ classify [x | SettingClassify x <- s] i
-            return $ Left i{ideaHint = if "Parse error" `isPrefixOf` msg then msg else "Parse error: " ++ msg}
+            return $ Left i
 
 
 -- | Find which hints a list of settings implies.
diff --git a/src/CmdLine.hs b/src/CmdLine.hs
--- a/src/CmdLine.hs
+++ b/src/CmdLine.hs
@@ -185,7 +185,7 @@
     ,CmdHSE
         {} &= explicit &= name "hse"
     ] &= program "hlint" &= verbosity
-    &=  summary ("HLint v" ++ showVersion version ++ ", (C) Neil Mitchell 2006-2016")
+    &=  summary ("HLint v" ++ showVersion version ++ ", (C) Neil Mitchell 2006-2017")
     where
         nam xs = nam_ xs &= name [head xs]
         nam_ xs = def &= explicit &= name xs
diff --git a/src/Hint/Monad.hs b/src/Hint/Monad.hs
--- a/src/Hint/Monad.hs
+++ b/src/Hint/Monad.hs
@@ -30,6 +30,9 @@
 foldM_ f a xs = foldM f a xs >> return ()
 folder f a xs = foldM f a xs >> return () -- foldM_ f a xs
 yes = mapM async ds >>= mapM wait >> return () -- mapM async ds >>= mapM_ wait
+main = "wait" ~> do f a $ sleep 10
+main = f $ do g a $ sleep 10 -- g a $ sleep 10
+main = do f a $ sleep 10 -- f a $ sleep 10
 </TEST>
 -}
 
@@ -50,19 +53,24 @@
 
 
 monadHint :: DeclHint
-monadHint _ _ d = concatMap (monadExp d) $ universeBi d
+monadHint _ _ d = concatMap (monadExp d) $ universeParentExp d
 
-monadExp :: Decl_ -> Exp_ -> [Idea]
-monadExp decl x = case x of
+monadExp :: Decl_ -> (Maybe (Int, Exp_), Exp_) -> [Idea]
+monadExp decl (parent, x) = case x of
         (view -> App2 op x1 x2) | op ~= ">>" -> f x1
         Do _ xs -> [warn "Redundant return" x (Do an y) rs | Just (y, rs) <- [monadReturn xs]] ++
                    [warn "Use join" x (Do an y) rs | Just (y, rs) <- [monadJoin xs ['a'..'z']]] ++
-                   [warn "Redundant do" x y [Replace Expr (toSS x) [("y", toSS y)] "y"] | [Qualifier _ y] <- [xs]] ++
+                   [warn "Redundant do" x y [Replace Expr (toSS x) [("y", toSS y)] "y"]
+                        | [Qualifier _ y] <- [xs], not $ doOperator parent y] ++
                    [suggest "Use let" x (Do an y) rs | Just (y, rs) <- [monadLet xs]] ++
                    concat [f x | Qualifier _ x <- init xs]
         _ -> []
     where
         f x = [warn ("Use " ++ name) x y r  | Just (name,y, r) <- [monadCall x], fromNamed decl /= name]
+
+-- Sometimes people write a * do a + b, to avoid brackets
+doOperator (Just (1, InfixApp _ _ op _)) InfixApp{} | not $ isDol op = True
+doOperator _ _ = False
 
 middle :: (b -> d) -> (a, b, c) -> (a, d, c)
 middle f (a,b,c) = (a, f b, c)
