diff --git a/data/Default.hs b/data/Default.hs
--- a/data/Default.hs
+++ b/data/Default.hs
@@ -27,7 +27,14 @@
 error = hPutStr stdout ==> putStr
 error = hPutStrLn stdout ==> putStrLn
 error = hPrint stdout ==> print
+error = hWaitForInput a 0 ==> hReady a
+error = hPutStrLn a (show b) ==> hPrint a b
+error = hIsEOF stdin ==> isEOF
 
+-- EXIT
+
+error = exitWith ExitSuccess ==> exitSuccess
+
 -- ORD
 
 error = not (a == b) ==> a /= b where note = "incorrect if either value is NaN"
@@ -50,6 +57,8 @@
 error = showsPrec 0 x "" ==> show x
 error = readsPrec 0 ==> reads
 error = showsPrec 0 ==> shows
+warn = showIntAtBase 16 intToDigit ==> showHex
+warn = showIntAtBase 8 intToDigit ==> showOct
 
 -- LIST
 
@@ -64,6 +73,7 @@
 error = take (length x - 1) x ==> init x
 error = isPrefixOf (reverse x) (reverse y) ==> isSuffixOf x y
 error = foldr (++) [] ==> concat
+error = foldl (++) [] ==> concat
 error = span (not . p) ==> break p
 error = break (not . p) ==> span p
 error = concatMap (++ "\n") ==> unlines
@@ -85,6 +95,12 @@
 error "Use any" = null (filter f x) ==> not (any f x)
 error "Use any" = filter f x == [] ==> not (any f x)
 error = filter f x /= [] ==> any f x
+error = any ((==) a) ==> elem a
+error = any (== a) ==> elem a
+error = any (a ==) ==> elem a
+error = all ((/=) a) ==> notElem a
+error = all (/= a) ==> notElem a
+error = all (a /=) ==> notElem a
 
 -- FOLDS
 
@@ -109,6 +125,7 @@
 error = foldr1 max   ==> maximum
 error = foldl1 min   ==> minimum
 error = foldr1 min   ==> minimum
+error = foldr mplus mzero ==> msum
 
 -- FUNCTION
 
@@ -124,6 +141,16 @@
 error "Redundant flip" = flip f x y ==> f y x where _ = isApp original
 warn  = (\a b -> o (f a) (f b)) ==> o `Data.Function.on` f
 
+-- CHAR
+
+error = a >= 'a' && a <= 'z' ==> isAsciiLower a
+error = a >= 'A' && a <= 'Z' ==> isAsciiUpper a
+error = a >= '0' && a <= '9' ==> isDigit a
+error = a >= '0' && a <= '7' ==> isOctDigit a
+error = not (isControl a) ==> isPrint a
+error = isLower a || isUpper a ==> isAlpha a
+error = isAlpha a || isDigit a ==> isAlphaNum a
+
 -- BOOL
 
 error "Redundant ==" = a == True ==> a
@@ -176,9 +203,17 @@
 error = sequence_ (map f x) ==> mapM_ f x
 warn  = flip mapM ==> Control.Monad.forM
 warn  = flip mapM_ ==> Control.Monad.forM_
+warn  = flip forM ==> mapM
+warn  = flip forM_ ==> mapM_
 error = when (not x) ==> unless x
 error = x >>= id ==> Control.Monad.join x
 error = liftM f (liftM g x) ==> liftM (f . g) x
+warn = a >> return () ==> void a
+warn = fmap (const ()) ==> void
+error = flip (>=>) ==> (<=<)
+error = flip (<=<) ==> (>=>)
+error = a >> forever a ==> forever a
+warn = liftM2 id ==> ap
 
 -- MONAD LIST
 
@@ -190,6 +225,17 @@
 error = mapM f (map g x) ==> mapM (f . g) x
 error = mapM_ f (map g x) ==> mapM_ (f . g) x
 
+-- APPLICATIVE / TRAVERSABLE
+
+error = flip traverse ==> for
+error = flip for ==> traverse
+error = flip traverse_ ==> for_
+error = flip for_ ==> traverse_
+error = foldr (*>) (pure ()) ==> sequenceA_
+error = foldr (<|>) empty ==> asum
+error = liftA2 (flip ($)) ==> (<**>)
+error = Just <$> a <|> pure Nothing ==> optional a
+
 -- LIST COMP
 
 warn  "Use list comprehension" = (if b then [x] else []) ==> [x | b]
@@ -226,7 +272,14 @@
 error = (if isJust x then fromJust x else y) ==> fromMaybe y x
 error = isJust x && (fromJust x == y) ==> x == Just y
 error = mapMaybe f (map g x) ==> mapMaybe (f . g) x
+error = fromMaybe a (fmap f x) ==> maybe a f x
+warn = [x | Just x <- a] ==> Data.Maybe.catMaybes a
 
+-- EITHER
+
+error = [a | Left a <- a] ==> lefts a
+error = [a | Right a <- a] ==> rights a
+
 -- INFIX
 
 warn "Use infix" = X.elem x y ==> x `X.elem` y where _ = not (isInfixApp original) && not (isParen result)
@@ -256,15 +309,31 @@
 warn  "Use 1" = x ^ 0 ==> 1
 warn  = round (x - 0.5) ==> floor x
 
+-- CONCURRENT
+
+warn = mapM_ (writeChan a) ==> writeList2Chan a
+
 -- EXCEPTION
 
 error "Use Control.Exception.catch" = Prelude.catch ==> Control.Exception.catch where note = "Prelude.catch does not catch most exceptions"
 warn = flip Control.Exception.catch ==> handle
+warn = flip handle ==> Control.Exception.catch
 warn = flip (catchJust p) ==> handleJust p
+warn = flip (handleJust p) ==> catchJust p
 warn = Control.Exception.bracket b (const a) (const t) ==> Control.Exception.bracket_ b a t
 warn = Control.Exception.bracket (openFile x y) hClose ==> withFile x y
 warn = Control.Exception.bracket (openBinaryFile x y) hClose ==> withBinaryFile x y
+warn = throw (ErrorCall a) ==> error a
+error = a `seq` return a ==> Control.Exception.evaluate a
+error = toException NonTermination ==> nonTermination
+error = toException NestedAtomically ==> nestedAtomically
 
+
+-- WEAK POINTERS
+
+error = mkWeak a a b ==> mkWeakPtr a b
+error = mkWeak a (a, b) c ==> mkWeakPair a b c
+
 -- EVALUATE
 
 -- TODO: These should be moved in to HSE\Evaluate.hs and applied
@@ -395,6 +464,7 @@
 import Prelude hiding (catch); no = catch
 import Control.Exception as E; no = E.catch
 main = do f; putStrLn $ show x -- print x
+main = map (writer,) $ map arcObj $ filter (rdfPredEq (Res dctreferences)) ts -- map ((writer,) . arcObj) (filter (rdfPredEq (Res dctreferences)) ts)
 
 import Prelude \
 yes = flip mapM -- Control.Monad.forM
diff --git a/hlint.cabal b/hlint.cabal
--- a/hlint.cabal
+++ b/hlint.cabal
@@ -1,7 +1,7 @@
 cabal-version:      >= 1.6
 build-type:         Simple
 name:               hlint
-version:            1.8.20
+version:            1.8.21
 -- license is GPL v2 only
 license:            GPL
 license-file:       LICENSE
diff --git a/src/HSE/Bracket.hs b/src/HSE/Bracket.hs
--- a/src/HSE/Bracket.hs
+++ b/src/HSE/Bracket.hs
@@ -31,6 +31,7 @@
         List{} -> True
         LeftSection{} -> True
         RightSection{} -> True
+        TupleSection{} -> True
         RecConstr{} -> True
         ListComp{} -> True
         EnumFrom{} -> True
diff --git a/src/HSE/Util.hs b/src/HSE/Util.hs
--- a/src/HSE/Util.hs
+++ b/src/HSE/Util.hs
@@ -82,6 +82,7 @@
 isPExplTypeArg PExplTypeArg{} = True; isPExplTypeArg _ = False
 isPFieldPun PFieldPun{} = True; isPFieldPun _ = False
 isFieldPun FieldPun{} = True; isFieldPun _ = False
+isPWildCard PWildCard{} = True; isPWildCard _ = False
 isPFieldWildcard PFieldWildcard{} = True; isPFieldWildcard _ = False
 isFieldWildcard FieldWildcard{} = True; isFieldWildcard _ = False
 isPViewPat PViewPat{} = True; isPViewPat _ = False
diff --git a/src/Hint/Structure.hs b/src/Hint/Structure.hs
--- a/src/Hint/Structure.hs
+++ b/src/Hint/Structure.hs
@@ -18,6 +18,13 @@
 foo x | otherwise = y -- foo x = y
 -- FIXME: #358 foo x = x + x where -- foo x = x + x
 foo x | a = b | True = d -- foo x | a = b ; | otherwise = d
+foo (Bar _ _ _ _) = x -- Bar{}
+foo (Bar _ x _ _) = x
+foo (Bar _ _) = x
+foo = case f v of _ -> x -- x
+foo = case v of v -> x -- x
+foo = case v of z -> z
+foo = case v of _ | False -> x
 </TEST>
 -}
 
@@ -29,7 +36,10 @@
 
 
 structureHint :: DeclHint
-structureHint _ _ x = concatMap (uncurry hints . swap) $ asPattern x
+structureHint _ _ x =
+    concatMap (uncurry hints . swap) (asPattern x) ++
+    concatMap patHint (universeBi x) ++
+    concatMap expHint (universeBi x)
 
 
 hints :: (String -> Pattern -> Idea) -> Pattern -> [Idea]
@@ -84,3 +94,18 @@
         match o@(Match a b pat rhs bind) = (Pattern pat rhs bind, \msg (Pattern pat rhs bind) -> warn msg o $ Match a b pat rhs bind)
         match o@(InfixMatch a p b ps rhs bind) = (Pattern (p:ps) rhs bind, \msg (Pattern (p:ps) rhs bind) -> warn msg o $ InfixMatch a p b ps rhs bind)
         alt o@(Alt a pat rhs bind) = [(Pattern [pat] (fromGuardedAlts rhs) bind, \msg (Pattern [pat] rhs bind) -> warn msg o $ Alt a pat (toGuardedAlts rhs) bind)]
+
+
+
+-- Should these hints be in the same module? They are less structure, and more about pattern matching
+-- Or perhaps the entire module should be renamed Pattern, since it's all about patterns
+patHint :: Pat_ -> [Idea]
+patHint o@(PApp _ name args) | length args >= 3 && all isPWildCard args = [warn "Use record patterns" o $ PRec an name []]
+patHint _ = []
+
+
+expHint :: Exp_ -> [Idea]
+expHint o@(Case _ _ [Alt _ PWildCard{} (UnGuardedAlt _ e) Nothing]) = [warn "Redundant case" o e]
+expHint o@(Case _ (Var _ x) [Alt _ (PVar _ y) (UnGuardedAlt _ e) Nothing])
+    | x =~= UnQual an y = [warn "Redundant case" o e]
+expHint _ = []
diff --git a/src/Settings.hs b/src/Settings.hs
--- a/src/Settings.hs
+++ b/src/Settings.hs
@@ -161,11 +161,15 @@
 -- find definitions in a source file
 findSettings :: ParseFlags -> FilePath -> IO (String, [Setting])
 findSettings flags file = do
-    x <- parseResult $ parseFile flags file
-    let xs = concatMap (findSetting $ UnQual an) (moduleDecls x)
-        s = unlines $ ["-- hints found in " ++ file] ++ map prettyPrint xs ++ ["-- no hints found" | null xs]
-        r = concatMap (readSetting emptyScope) xs
-    return (s,r)
+    x <- parseFile flags file
+    case snd x of
+        ParseFailed sl msg ->
+            return ("-- Parse error " ++ showSrcLoc sl ++ ": " ++ msg, [])
+        ParseOk m -> do
+            let xs = concatMap (findSetting $ UnQual an) (moduleDecls m)
+                s = unlines $ ["-- hints found in " ++ file] ++ map prettyPrint xs ++ ["-- no hints found" | null xs]
+                r = concatMap (readSetting emptyScope) xs
+            return (s,r)
 
 
 findSetting :: (Name S -> QName S) -> Decl_ -> [Decl_]
