diff --git a/CHANGES.txt b/CHANGES.txt
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,5 +1,20 @@
 Changelog for HLint (* = breaking change)
 
+2.1.7, released 2018-07-03
+    #483, don't break quasi quotes when suggesting const
+    #404, remove the "Unnecessary hiding" hint introduced in #338
+    #162, make avoiding lambda with `infix` give a different name
+    #507, rename id x ==> x to redundant id
+    #286, improve the duplicate pragma message
+    #399, suggest (& f) ==> f
+    #136, don't suggest eta-reducing runST
+    #345, add catMaybes/fmap ==> mapMaybe
+    #345, add foldMap id ==> fold
+    #364, suggest >> instead of >>= \_ ->
+    #502, DeriveTraversable implies DeriveFoldable and DeriveFunctor
+    Add hints about fusing traverse/map
+    Better names for mapM/map fusion hints and others
+    #498, change the output to say "Perhaps:" rather than "Why not:"
 2.1.6, released 2018-06-16
     Match on explicit brackets at the root of a match expression
     #470, suggest TupleSections
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -16,6 +16,7 @@
 * Some transformed programs may require additional type signatures, particularly if the transformations trigger the monomorphism restriction or involve rank-2 types.
 * The `RebindableSyntax` extension can cause HLint to suggest incorrect changes.
 * HLint turns on many language extensions so it can parse more documents, occasionally some break otherwise legal syntax - e.g. `{-#INLINE foo#-}` doesn't work with `MagicHash`, `foo $bar` means something different with `TemplateHaskell`. These extensions can be disabled with `-XNoMagicHash` or `-XNoTemplateHaskell` etc.
+* HLint doesn't run any custom preprocessors, e.g. [markdown-unlit](https://hackage.haskell.org/package/markdown-unlit) or [record-dot-preprocessor](https://hackage.haskell.org/package/record-dot-preprocessor), so code making use of them will usually fail to parse.
 
 ## Installing and running HLint
 
@@ -29,19 +30,19 @@
 darcs-2.1.2\src\CommandLine.lhs:94:1: Warning: Use concatMap
 Found:
     concat $ map escapeC s
-Why not:
+Perhaps:
     concatMap escapeC s
 
 darcs-2.1.2\src\CommandLine.lhs:103:1: Suggestion: Use fewer brackets
 Found:
     ftable ++ (map (\ (c, x) -> (toUpper c, urlEncode x)) ftable)
-Why not:
+Perhaps:
     ftable ++ map (\ (c, x) -> (toUpper c, urlEncode x)) ftable
 
 darcs-2.1.2\src\Darcs\Patch\Test.lhs:306:1: Warning: Use a more efficient monadic variant
 Found:
     mapM (delete_line (fn2fp f) line) old
-Why not:
+Perhaps:
     mapM_ (delete_line (fn2fp f) line) old
 
 ... lots more hints ...
diff --git a/data/hlint.yaml b/data/hlint.yaml
--- a/data/hlint.yaml
+++ b/data/hlint.yaml
@@ -95,7 +95,7 @@
     - warn: {lhs: reverse (sortOn f x), rhs: sortOn (Data.Ord.Down . f) x, name: Avoid reverse}
     - warn: {lhs: reverse (sort x), rhs: sortOn Data.Ord.Down x, name: Avoid reverse}
     - hint: {lhs: flip (g `on` h), rhs: flip g `on` h, name: Move flip}
-    - hint: {lhs: (f `on` g) `on` h, rhs: f `on` (g . h)}
+    - hint: {lhs: (f `on` g) `on` h, rhs: f `on` (g . h), name: Fuse on/on}
 
 
     # READ/SHOW
@@ -153,7 +153,7 @@
     - warn: {lhs: map (uncurry f) (zip x y), rhs: zipWith f x y}
     - hint: {lhs: map f (zip x y), rhs: zipWith (curry f) x y, side: isVar f}
     - warn: {lhs: not (elem x y), rhs: notElem x y}
-    - hint: {lhs: foldr f z (map g x), rhs: foldr (f . g) z x}
+    - hint: {lhs: foldr f z (map g x), rhs: foldr (f . g) z x, name: Fuse foldr/map}
     - warn: {lhs: "x ++ concatMap (' ':) y", rhs: "unwords (x:y)"}
     - warn: {lhs: intercalate " ", rhs: unwords}
     - hint: {lhs: concat (intersperse x y), rhs: intercalate x y, side: notEq x " "}
@@ -198,6 +198,7 @@
     - warn: {lhs: sequence (fmap f x), rhs: traverse f x}
     - warn: {lhs: sequenceA_ (map f x), rhs: traverse_ f x}
     - warn: {lhs: sequenceA_ (fmap f x), rhs: traverse_ f x}
+    - warn: {lhs: foldMap id, rhs: fold}
 
     # BY
 
@@ -246,10 +247,11 @@
     - hint: {lhs: "\\(x,y) -> f x y", rhs: uncurry f, note: IncreasesLaziness, name: Use uncurry}
     - warn: {lhs: ($) . f, rhs: f, name: Redundant $}
     - warn: {lhs: (f $), rhs: f, name: Redundant $}
+    - warn: {lhs: (Data.Function.& f), rhs: f, name: Redundant Data.Function.&}
     - hint: {lhs: \x -> y, rhs: const y, side: isAtom y && not (isWildcard y)}
         # isWildcard because some people like to put brackets round them even though they are atomic
     - warn: {lhs: flip f x y, rhs: f y x, side: isApp original, name: Redundant flip}
-    - warn: {lhs: id x, rhs: x, side: not (isTypeApp x), name: Evaluate}
+    - warn: {lhs: id x, rhs: x, side: not (isTypeApp x), name: Redundant id}
     - warn: {lhs: id . x, rhs: x, name: Redundant id}
     - warn: {lhs: x . id, rhs: x, name: Redundant id}
     - warn: {lhs: "((,) x)", rhs: "(_noParen_ x,)", name: Use tuple-section, note: RequiresExtension TupleSections}
@@ -365,6 +367,7 @@
     - warn: {lhs: mapM (uncurry f) (zip l m), rhs: zipWithM f l m}
     - warn: {lhs: mapM_ (void . f), rhs: mapM_ f}
     - warn: {lhs: forM_ x (void . f), rhs: forM_ x f}
+    - warn: {lhs: a >>= \_ -> b, rhs: a >> b}
 
     # STATE MONAD
 
@@ -380,8 +383,10 @@
     - warn: {lhs: sequence_ (replicate n x), rhs: Control.Monad.replicateM_ n x}
     - warn: {lhs: mapM f (replicate n x), rhs: Control.Monad.replicateM n (f x)}
     - warn: {lhs: mapM_ f (replicate n x), rhs: Control.Monad.replicateM_ n (f x)}
-    - warn: {lhs: mapM f (map g x), rhs: mapM (f . g) x}
-    - warn: {lhs: mapM_ f (map g x), rhs: mapM_ (f . g) x}
+    - warn: {lhs: mapM f (map g x), rhs: mapM (f . g) x, name: Fuse mapM/map}
+    - warn: {lhs: mapM_ f (map g x), rhs: mapM_ (f . g) x, name: Fuse mapM_/map}
+    - warn: {lhs: traverse f (map g x), rhs: traverse (f . g) x, name: Fuse traverse/map}
+    - warn: {lhs: traverse_ f (map g x), rhs: traverse_ (f . g) x, name: Fuse traverse_/map}
     - warn: {lhs: mapM id, rhs: sequence}
     - warn: {lhs: mapM_ id, rhs: sequence_}
     - warn: {lhs: sequence (return a), rhs: return <$> a}
@@ -431,6 +436,7 @@
     - warn: {lhs: not (isJust x), rhs: isNothing x}
     - warn: {lhs: "maybe [] (:[])", rhs: maybeToList}
     - warn: {lhs: catMaybes (map f x), rhs: mapMaybe f x}
+    - warn: {lhs: catMaybes (fmap f x), rhs: mapMaybe f x}
     - hint: {lhs: case x of Nothing -> y; Just a -> a , rhs: fromMaybe y x}
     - warn: {lhs: if isNothing x then y else f (fromJust x), rhs: maybe y f x}
     - warn: {lhs: if isJust x then f (fromJust x) else y, rhs: maybe y f x}
@@ -447,7 +453,7 @@
     - warn: {lhs: if isNothing x then y else fromJust x, rhs: fromMaybe y x}
     - warn: {lhs: if isJust x then fromJust x else y, rhs: fromMaybe y x}
     - warn: {lhs: isJust x && (fromJust x == y), rhs: x == Just y}
-    - warn: {lhs: mapMaybe f (map g x), rhs: mapMaybe (f . g) x}
+    - warn: {lhs: mapMaybe f (map g x), rhs: mapMaybe (f . g) x, name: Fuse mapMaybe/map}
     - warn: {lhs: fromMaybe a (fmap f x), rhs: maybe a f x}
     - warn: {lhs: fromMaybe a (f <$> x), rhs: maybe a f x}
     - warn: {lhs: mapMaybe id, rhs: catMaybes}
@@ -809,6 +815,7 @@
 # yes = foldr (\ curr acc -> (+ 1) curr : acc) [] -- map (\ curr -> (+ 1) curr)
 # yes = foldr (\ curr acc -> curr + curr : acc) [] -- map (\ curr -> curr + curr)
 # no = foo $ (,) x $ do {this is a test; and another test}
+# {-# LANGUAGE QuasiQuotes #-}; no = f (\url -> [hamlet|foo @{url}|])
 #
 # import Prelude \
 # yes = flip mapM -- Control.Monad.forM
diff --git a/data/hs-lint.el b/data/hs-lint.el
--- a/data/hs-lint.el
+++ b/data/hs-lint.el
@@ -12,7 +12,7 @@
 ;; /Users/ott/projects/lang-exp/haskell/test.hs:52:1: Eta reduce
 ;; Found:
 ;;   count1 p l = length (filter p l)
-;; Why not:
+;; Perhaps:
 ;;   count1 p = length . filter p
 
 
@@ -52,11 +52,11 @@
 ;; ^\(.*?\):\([0-9]+\):\([0-9]+\): .*
 ;; Found:
 ;; \s +\(.*\)
-;; Why not:
+;; Perhaps:
 ;; \s +\(.*\)
 
 (defvar hs-lint-regex
-  "^\\(.*?\\):\\([0-9]+\\):\\([0-9]+\\): .*[\n\C-m]Found:[\n\C-m]\\s +\\(.*\\)[\n\C-m]Why not:[\n\C-m]\\s +\\(.*\\)[\n\C-m]"
+  "^\\(.*?\\):\\([0-9]+\\):\\([0-9]+\\): .*[\n\C-m]Found:[\n\C-m]\\s +\\(.*\\)[\n\C-m]Perhaps:[\n\C-m]\\s +\\(.*\\)[\n\C-m]"
   "Regex for HLint messages")
 
 (defun make-short-string (str maxlen)
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.1.6
+version:            2.1.7
 license:            BSD3
 license-file:       LICENSE
 category:           Development
diff --git a/src/CC.hs b/src/CC.hs
--- a/src/CC.hs
+++ b/src/CC.hs
@@ -99,7 +99,7 @@
         , T.pack from
         , "```"
         , ""
-        , "Why not"
+        , "Perhaps"
         , ""
         , "```"
         , T.pack to
diff --git a/src/Hint/Extensions.hs b/src/Hint/Extensions.hs
--- a/src/Hint/Extensions.hs
+++ b/src/Hint/Extensions.hs
@@ -210,7 +210,7 @@
 used DeriveDataTypeable = hasDerive ["Data","Typeable"]
 used DeriveFunctor = hasDerive ["Functor"]
 used DeriveFoldable = hasDerive ["Foldable"]
-used DeriveTraversable = hasDerive ["Traversable"]
+used DeriveTraversable = hasDerive ["Traversable","Foldable","Functor"]
 used DeriveGeneric = hasDerive ["Generic","Generic1"]
 used GeneralizedNewtypeDeriving = not . null . derivesNewtype . derives
 used LambdaCase = hasS isLCase
diff --git a/src/Hint/Import.hs b/src/Hint/Import.hs
--- a/src/Hint/Import.hs
+++ b/src/Hint/Import.hs
@@ -33,73 +33,6 @@
 import Char(foo) -- import Data.Char(foo)
 import IO(foo)
 import IO as X -- import System.IO as X; import System.IO.Error as X; import Control.Exception  as X (bracket,bracket_)
-import A hiding (a) -- import A
-import A hiding (a, b); foo = a -- import A hiding (a)
-import A hiding (a, b); foo = A.a -- import A hiding (a)
-import A as B hiding (a) -- import A as B
-import A as B hiding (a, b); foo = a -- import A as B hiding (a)
-import A as B hiding (a, b); foo = B.a -- import A as B hiding (a)
-import qualified A hiding (a) -- import qualified A
-import qualified A hiding (a, b); foo = A.a -- import qualified A hiding (a)
-import qualified A as B hiding (a, b); foo = B.a -- import qualified A as B hiding (a)
-import A hiding ((+)) -- import A
-import A hiding ((+), (*)); foo = (+) -- import A hiding ((+))
-import A hiding ((+), (*)); foo = (+x) -- import A hiding ((+))
-import A hiding ((+), (*)); foo = (x+) -- import A hiding ((+))
-import A hiding ((+), (*)); foo = x+y -- import A hiding ((+))
-import A hiding ((+), (*)); foo = (A.+) -- import A hiding ((+))
-import A hiding ((+), (*)); foo = (A.+ x) -- import A hiding ((+))
-import A hiding ((+), (*)); foo = (x A.+) -- import A hiding ((+))
-import A hiding ((+), (*)); foo = x A.+ y -- import A hiding ((+))
-import A as B hiding ((+)) -- import A as B
-import A as B hiding ((+), (*)); foo = (+) -- import A as B hiding ((+))
-import A as B hiding ((+), (*)); foo = (x+) -- import A as B hiding ((+))
-import A as B hiding ((+), (*)); foo = (+x) -- import A as B hiding ((+))
-import A as B hiding ((+), (*)); foo = x+y -- import A as B hiding ((+))
-import A as B hiding ((+), (*)); foo = (B.+) -- import A as B hiding ((+))
-import A as B hiding ((+), (*)); foo = (x B.+) -- import A as B hiding ((+))
-import A as B hiding ((+), (*)); foo = (B.+ x) -- import A as B hiding ((+))
-import A as B hiding ((+), (*)); foo = x B.+ y -- import A as B hiding ((+))
-import qualified A hiding ((+)) -- import qualified A
-import qualified A hiding ((+), (*)); foo = (A.+) -- import qualified A hiding ((+))
-import qualified A hiding ((+), (*)); foo = (x A.+) -- import qualified A hiding ((+))
-import qualified A hiding ((+), (*)); foo = (A.+ x) -- import qualified A hiding ((+))
-import qualified A hiding ((+), (*)); foo = x A.+ y -- import qualified A hiding ((+))
-import qualified A as B hiding ((+), (*)); foo = (B.+) -- import qualified A as B hiding ((+))
-import qualified A as B hiding ((+), (*)); foo = (x B.+) -- import qualified A as B hiding ((+))
-import qualified A as B hiding ((+), (*)); foo = (B.+ x) -- import qualified A as B hiding ((+))
-import qualified A as B hiding ((+), (*)); foo = x B.+ y -- import qualified A as B hiding ((+))
-module Foo (a) where; import A hiding (a)
-module Foo (a) where; import A hiding (a, b) -- import A hiding (a)
-module Foo (A.a) where; import A hiding (a, b) -- import A hiding (a)
-module Foo (a) where; import A as B hiding (a)
-module Foo (a) where; import A as B hiding (a, b) -- import A as B hiding (a)
-module Foo (B.a) where; import A as B hiding (a, b) -- import A as B hiding (a)
-module Foo (a) where; import qualified A hiding (a) -- import qualified A
-module Foo (A.a) where; import qualified A hiding (a, b) -- import qualified A hiding (a)
-module Foo (B.a) where; import qualified A as B hiding (a, b) -- import qualified A as B hiding (a)
-module Foo (module A) where; import A hiding (a, b, c)
-module Foo (module B) where; import A as B hiding (a, b, c)
-module Foo (module A) where; import qualified A hiding (a, b, c) -- import qualified A
-module Foo (module B) where; import qualified A as B hiding (a, b, c) -- import qualified A as B
-module Foo ((+)) where; import A hiding ((+))
-module Foo ((+)) where; import A hiding ((+), (*)) -- import A hiding ((+))
-module Foo ((A.+)) where; import A hiding ((+), (*)) -- import A hiding ((+))
-module Foo ((+)) where; import A as B hiding ((+))
-module Foo ((+)) where; import A as B hiding ((+), (*)) -- import A as B hiding ((+))
-module Foo ((B.+)) where; import A as B hiding ((+), (*)) -- import A as B hiding ((+))
-module Foo ((+)) where; import qualified A hiding ((+)) -- import qualified A
-module Foo ((A.+)) where; import qualified A hiding ((+), (*)) -- import qualified A hiding ((+))
-module Foo ((B.+)) where; import qualified A as B hiding ((+), (*)) -- import qualified A as B hiding ((+))
-module Foo (module A) where; import A hiding ((+), (*), (/))
-module Foo (module B) where; import A as B hiding ((+), (*), (/))
-module Foo (module A) where; import qualified A hiding ((+), (*), (/)) -- import qualified A
-module Foo (module B) where; import qualified A as B hiding ((+), (*), (/)) -- import qualified A as B
-{-# LANGUAGE QuasiQuotes #-}; import A hiding (a); [a||]
-{-# LANGUAGE QuasiQuotes #-}; import A hiding (a); [A.a||]
-{-# LANGUAGE QuasiQuotes #-}; import A as B hiding (a); [B.a||]
-{-# LANGUAGE QuasiQuotes #-}; import qualified A hiding (a); [A.a||]
-{-# LANGUAGE QuasiQuotes #-}; import qualified A as B hiding (a); [B.a||]
 </TEST>
 -}
 
@@ -112,53 +45,16 @@
 import Refact.Types hiding (ModuleName)
 import qualified Refact.Types as R
 import Data.List.Extra
-import Data.Either (partitionEithers)
 import Data.Maybe
 import Prelude
-import Data.Map (Map)
-import qualified Data.Map as Map
-import Data.Set (Set)
-import qualified Data.Set as Set
 
 
 importHint :: ModuHint
 importHint _ x = concatMap (wrap . snd) (groupSort
                  [((fromNamed $ importModule i,importPkg i),i) | i <- universeBi x, not $ importSrc i]) ++
-                 concatMap (\x -> hierarchy x ++ combine1 x ++ hidden reexported unqual quals x) (universeBi x)
-    where
-        -- Names of all re-exported modules
-        reexported :: Set String
-        reexported = Set.fromList [ fromModuleName n | EModuleContents _ n <- universeBi x ]
+                 concatMap (\x -> hierarchy x ++ combine1 x) (universeBi x)
 
-        -- Unqualified expressions and exported expressions
-        unqual :: Set String
-        unqual = Set.fromList (mapMaybe f qnames) `Set.union` Set.fromList qqUnqual
-            where f :: QName S -> Maybe String
-                  f (UnQual _ n) = Just (fromNamed n)
-                  f _ = Nothing
 
-        -- Qualified expressions and exported expressions
-        quals :: Map String (Set String)
-        quals = Map.fromListWith Set.union (map (second Set.singleton) qqQuals ++ mapMaybe f qnames)
-            where f (Qual _ m n) = Just (fromModuleName m, Set.singleton (fromNamed n))
-                  f _ = Nothing
-
-        -- Unqualified quasi-quoters like [foo|...|]
-        qqUnqual :: [String]
-        -- Qualified quasi-quoters like [Foo.bar|...|]
-        qqQuals :: [(String, String)]
-        (qqUnqual, qqQuals) = partitionEithers [ f n | QuasiQuote (_ :: S) n _ <- universeBi x ]
-            where f :: String -> Either String (String, String)
-                  f n = maybe (Left n) Right (stripInfixEnd "." n)
-
-        qnames :: [QName S]
-        qnames = concat
-            [ [ n | Var      (_ :: S) n <- universeBi x ]
-            , [ n | VarQuote (_ :: S) n <- universeBi x ]
-            , [ n | QVarOp   (_ :: S) n <- universeBi x ]
-            , [ n | EVar     (_ :: S) n <- universeBi x ]
-            ]
-
 wrap :: [ImportDecl S] -> [Idea]
 wrap o = [ rawIdea Warning "Use fewer imports" (srcInfoSpan $ ann $ head o) (f o) (Just $ f x) [] rs
          | Just (x, rs) <- [simplify o]]
@@ -215,7 +111,7 @@
     ,"Data" * "Ratio"
     ,"System" * "Directory"
 
-    -- Special, see bug #393
+    -- Special, see bug https://code.google.com/archive/p/ndmitchell/issues/393
     -- ,"System" * "IO"
 
     -- Do not encourage use of old-locale/old-time over haskell98
@@ -247,36 +143,3 @@
 desugarQual :: ImportDecl S -> ImportDecl S
 desugarQual x | importQualified x && isNothing (importAs x) = x{importAs=Just (importModule x)}
               | otherwise = x
-
--- Suggest removing unnecessary "hiding" clauses in imports. Currently this only
--- works for expressions.
-hidden :: Set String -> Set String -> Map String (Set String) -> ImportDecl S -> [Idea]
-hidden reexported unqual quals i@ImportDecl{importSpecs = Just (ImportSpecList loc True xs)}
-    -- If the module is re-exported and not imported qualified, we can't prune
-    -- any identifiers from the hiding clause
-    | not (importQualified i) && as `Set.member` reexported = []
-    | otherwise =
-        case partition isUsed xs of
-            (_, []) -> []
-            ([], _) -> [suggest "Unnecessary hiding" i i{importSpecs = Nothing} [Delete Import (toSS i)]]
-            (xs, _) ->
-                let newImp = i{importSpecs = Just (ImportSpecList loc True xs)}
-                in [suggest "Unnecessary hiding" i newImp [Replace Import (toSS i) [] (prettyPrint newImp)]]
-    where
-        isUsed :: ImportSpec S -> Bool
-        isUsed (IVar _ n) = Set.member (fromNamed n) vars
-        isUsed _ = True
-
-        vars :: Set String
-        vars =
-          if importQualified i
-            then qual
-            else qual `Set.union` unqual
-
-        qual :: Set String
-        qual = fromMaybe Set.empty (Map.lookup as quals)
-
-        as :: String
-        as = fromModuleName (fromMaybe (importModule i) (importAs i))
-
-hidden _ _ _ _ = []
diff --git a/src/Hint/Lambda.hs b/src/Hint/Lambda.hs
--- a/src/Hint/Lambda.hs
+++ b/src/Hint/Lambda.hs
@@ -31,9 +31,13 @@
 fun mr = y mr
 fun x = f . g $ x -- fun = f . g
 f = foo (\y -> g x . h $ y) -- g x . h
+f = foo (\y -> g x . h $ y) -- @Message Avoid lambda
 f = foo ((*) x) -- (x *)
 f = (*) x
 f = foo (flip op x) -- (`op` x)
+f = foo (flip op x) -- @Message Use section
+foo x = bar (\ d -> search d table) -- (`search` table)
+foo x = bar (\ d -> search d table) -- @Message Avoid lambda using `infix`
 f = flip op x
 f = foo (flip (*) x) -- (* x)
 f = foo (flip (-) x)
@@ -70,6 +74,7 @@
 no = blah (\ x -> case x of A -> a x; B -> b x)
 yes = blah (\ x -> (y, x, z+q)) -- (y, , z+q)
 yes = blah (\ x -> (y, x, z+x))
+tmp = map (\ x -> runST $ action x)
 {-# LANGUAGE QuasiQuotes #-}; authOAuth2 name = authOAuth2Widget [whamlet|Login via #{name}|] name
 {-# LANGUAGE QuasiQuotes #-}; authOAuth2 = foo (\name -> authOAuth2Widget [whamlet|Login via #{name}|] name)
 </TEST>
@@ -83,6 +88,7 @@
 import Util
 import Data.List.Extra
 import Data.Maybe
+import qualified Data.Set as Set
 import Refact.Types hiding (RType(Match))
 
 
@@ -138,8 +144,12 @@
 --      subts = [("a", toSS y), ("*", toSS v)]
 lambdaExp p o@(Paren _ (App _ (App _ (view -> Var_ "flip") (Var _ x)) y)) | allowRightSection $ fromNamed x =
     [suggestN "Use section" o $ RightSection an (QVarOp an x) y]
-lambdaExp p o@Lambda{} | maybe True (not . isInfixApp) p, (res, refact) <- niceLambdaR [] o, not $ isLambda res, not $ any isQuasiQuote $ universe res =
-    [(if isVar res || isCon res then warn else suggest) "Avoid lambda" o res (refact $ toSS o)]
+lambdaExp p o@Lambda{}
+    | maybe True (not . isInfixApp) p, (res, refact) <- niceLambdaR [] o
+    , not $ isLambda res, not $ any isQuasiQuote $ universe res, not $ "runST" `Set.member` freeVars o
+    , let name = "Avoid lambda" ++ (if countInfixNames res > countInfixNames o then " using `infix`" else "") =
+    [(if isVar res || isCon res then warn else suggest) name o res (refact $ toSS o)]
+    where countInfixNames x = length [() | RightSection _ (QVarOp _ (UnQual _ (Ident _ _))) _ <- universe x]
 lambdaExp p o@(Lambda _ pats x) | isLambda (fromParen x), null (universeBi pats :: [Exp_]), maybe True (not . isLambda) p =
     [suggest "Collapse lambdas" o (Lambda an pats body) [Replace Expr (toSS o) subts template]]
     where
diff --git a/src/Hint/Match.hs b/src/Hint/Match.hs
--- a/src/Hint/Match.hs
+++ b/src/Hint/Match.hs
@@ -111,6 +111,12 @@
     guard $ (freeVars e Set.\\ Set.filter (not . isUnifyVar) (freeVars hintRuleRHS))
             `Set.isSubsetOf` freeVars x
         -- check no unexpected new free variables
+
+    -- check it isn't going to get broken by QuasiQuotes as per #483
+    -- if we have lambdas we might be moving, and QuasiQuotes, we might inadvertantly break free vars
+    -- because quasi quotes don't show what free vars they make use of
+    guard $ not (any isLambda $ universe hintRuleLHS) || not (any isQuasiQuote $ universe x)
+
     guard $ checkSide hintRuleSide $ ("original",x) : ("result",res) : fromSubst u
     guard $ checkDefine decl parent res
     return (res, hintRuleNotes, [(s, toSS pos) | (s, pos) <- fromSubst u, ann pos /= an])
diff --git a/src/Hint/Pragma.hs b/src/Hint/Pragma.hs
--- a/src/Hint/Pragma.hs
+++ b/src/Hint/Pragma.hs
@@ -68,21 +68,22 @@
 pragmaIdea pidea =
   case pidea of
     SingleComment old new ->
-      mkIdea (srcInfoSpan . ann $ old)
+      mkFewer (srcInfoSpan . ann $ old)
         (prettyPrint old) (Just $ prettyPrint new) []
         [ModifyComment (toSS old) (prettyPrint new)]
     MultiComment repl delete new ->
-      mkIdea (srcInfoSpan . ann $ repl)
+      mkFewer (srcInfoSpan . ann $ repl)
         (f [repl, delete]) (Just $ prettyPrint new) []
         [ ModifyComment (toSS repl) (prettyPrint new)
         , ModifyComment (toSS delete) ""]
     OptionsToComment old new r ->
-      mkIdea (srcInfoSpan . ann . head $ old)
+      mkLanguage (srcInfoSpan . ann . head $ old)
         (f old) (Just $ f new) []
         r
     where
           f = unlines . map prettyPrint
-          mkIdea = rawIdea Warning "Use better pragmas"
+          mkFewer = rawIdea Warning "Use fewer LANGUAGE pragmas"
+          mkLanguage = rawIdea Warning "Use LANGUAGE pragmas"
 
 
 languageDupes :: [ModulePragma S] -> [Idea]
diff --git a/src/Idea.hs b/src/Idea.hs
--- a/src/Idea.hs
+++ b/src/Idea.hs
@@ -70,11 +70,11 @@
 showEx :: (String -> String) -> Idea -> String
 showEx tt Idea{..} = unlines $
     [showSrcLoc (getPointLoc ideaSpan) ++ ": " ++ (if ideaHint == "" then "" else show ideaSeverity ++ ": " ++ ideaHint)] ++
-    f "Found" (Just ideaFrom) ++ f "Why not" ideaTo ++
+    f "Found" (Just ideaFrom) ++ f "Perhaps" ideaTo ++
     ["Note: " ++ n | let n = showNotes ideaNote, n /= ""]
     where
         f msg Nothing = []
-        f msg (Just x) | null xs = [msg ++ " remove it."]
+        f msg (Just x) | null xs = [msg ++ " you should remove it."]
                        | otherwise = (msg ++ ":") : map ("  "++) xs
             where xs = lines $ tt x
 
diff --git a/src/Report.hs b/src/Report.hs
--- a/src/Report.hs
+++ b/src/Report.hs
@@ -56,7 +56,7 @@
     (case ideaTo of
         Nothing -> []
         Just to ->
-            ["Why not" ++ (if to == "" then " remove it." else "") ++ "<br/>"
+            ["Perhaps" ++ (if to == "" then " you should remove it." else "") ++ "<br/>"
             ,hsColourHTML to]) ++
     [let n = showNotes ideaNote in if n /= "" then "<span class='note'>Note: " ++ writeNote n ++ "</span>" else ""
     ,"</div>"
diff --git a/src/Test/Annotations.hs b/src/Test/Annotations.hs
--- a/src/Test/Annotations.hs
+++ b/src/Test/Annotations.hs
@@ -56,6 +56,7 @@
             if null bad then passed else sequence_ bad
 
         match "???" _ = True
+        match (word1 -> ("@Message",msg)) i = ideaHint i == msg
         match (word1 -> ("@Note",note)) i = map show (ideaNote i) == [note]
         match "@NoNote" i = null (ideaNote i)
         match (word1 -> ('@':sev, msg)) i = sev == show (ideaSeverity i) && match msg i
