diff --git a/CHANGES.txt b/CHANGES.txt
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,5 +1,8 @@
 Changelog for HLint
 
+1.9.1
+    #65, add flip (>>=) ==> (=<<) and the reverse
+    #61, add --json flag
 1.9
     Remove not (isControl x) ==> isPrint (not true for '\173')
     #57, warn on invalid pragmas
diff --git a/data/Default.hs b/data/Default.hs
--- a/data/Default.hs
+++ b/data/Default.hs
@@ -307,6 +307,8 @@
 error = fmap (const ()) ==> Control.Monad.void where _ = noQuickCheck
 error = flip (>=>) ==> (<=<) where _ = noQuickCheck
 error = flip (<=<) ==> (>=>) where _ = noQuickCheck
+error = flip (>>=) ==> (=<<) where _ = noQuickCheck
+error = flip (=<<) ==> (>>=) where _ = noQuickCheck
 warn  = (\x -> f x >>= g) ==> f Control.Monad.>=> g where _ = noQuickCheck
 warn  = (\x -> f =<< g x) ==> f Control.Monad.<=< g where _ = noQuickCheck
 error = a >> forever a ==> forever a where _ = noQuickCheck
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.9
+version:            1.9.1
 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
@@ -46,7 +46,7 @@
     where
         mns = map (scopeCreate . fst &&& id) ms
         hints = (if length ms <= 1 then noModules else id) hints_
-        noModules h = h{hintModules = \_ -> []} `mappend` mempty{hintModule = \a b -> hintModules h [(a,b)]}
+        noModules h = h{hintModules = const []} `mappend` mempty{hintModule = \a b -> hintModules h [(a,b)]}
 
 
 -- | Given a list of settings (a way to classify) and a list of hints, run them over a list of modules.
diff --git a/src/CmdLine.hs b/src/CmdLine.hs
--- a/src/CmdLine.hs
+++ b/src/CmdLine.hs
@@ -74,6 +74,7 @@
         ,cmdCppFile :: [FilePath]
         ,cmdCppSimple :: Bool
         ,cmdCppAnsi :: Bool
+        ,cmdJson :: Bool                -- ^ display hint data as JSON
         }
     | CmdGrep
         {cmdFiles :: [FilePath]    -- ^ which files to run it on, nothing = none given
@@ -125,6 +126,7 @@
         ,cmdCppFile = nam_ "cpp-file" &= typDir &= help "CPP pre-include file"
         ,cmdCppSimple = nam_ "cpp-simple" &= help "Use a simple CPP (strip # lines)"
         ,cmdCppAnsi = nam_ "cpp-ansi" &= help "Use CPP in ANSI compatibility mode"
+        ,cmdJson = nam_ "json" &= help "Display hint data as JSON"
         } &= auto &= explicit &= name "lint"
     ,CmdGrep
         {cmdFiles = def &= args &= typ "FILE/DIR"
diff --git a/src/Grep.hs b/src/Grep.hs
--- a/src/Grep.hs
+++ b/src/Grep.hs
@@ -23,7 +23,7 @@
     forM_ files $ \file -> do
         res <- parseModuleEx flags file Nothing
         case res of
-            Left (ParseError sl msg ctxt) -> do
+            Left (ParseError sl msg ctxt) ->
                 print $ rawIdea Warning (if "Parse error" `isPrefixOf` msg then msg else "Parse error: " ++ msg) (mkSrcSpan sl sl) ctxt Nothing []
             Right m ->
                 forM_ (applyHints [] rule [m]) $ \i ->
diff --git a/src/HLint.hs b/src/HLint.hs
--- a/src/HLint.hs
+++ b/src/HLint.hs
@@ -71,14 +71,14 @@
         putStrLn ""
 
 hlintTest :: Cmd -> IO ()
-hlintTest cmd@CmdTest{..} = do
+hlintTest cmd@CmdTest{..} =
     if notNull cmdProof then do
         files <- cmdHintFiles cmd
         s <- readSettings2 cmdDataDir files []
         let reps = if cmdReports == ["report.html"] then ["report.txt"] else cmdReports
         mapM_ (proof reps s) cmdProof
      else do
-        failed <- test cmd (\args -> do errs <- hlint args; when (length errs > 0) $ exitWith $ ExitFailure 1) cmdDataDir cmdGivenHints
+        failed <- test cmd (\args -> do errs <- hlint args; unless (null errs) $ exitWith $ ExitFailure 1) cmdDataDir cmdGivenHints
         when (failed > 0) exitFailure
 
 hlintGrep :: Cmd -> IO ()
@@ -128,16 +128,18 @@
         then applyHintFiles flags settings cmdFiles
         else concat <$> parallel [listM' =<< applyHintFile flags settings x Nothing | x <- cmdFiles]
     let (showideas,hideideas) = partition (\i -> cmdShowAll || ideaSeverity i /= Ignore) ideas
-    showItem <- if cmdColor then showANSI else return show
-    mapM_ (outStrLn . showItem) showideas
-
-    if null showideas then
-        when (cmdReports /= []) $ outStrLn "Skipping writing reports"
-     else
-        forM_ cmdReports $ \x -> do
-            outStrLn $ "Writing report to " ++ x ++ " ..."
-            writeReport cmdDataDir x showideas
-    outStrLn $
-        (let i = length showideas in if i == 0 then "No suggestions" else show i ++ " suggestion" ++ ['s'|i/=1]) ++
-        (let i = length hideideas in if i == 0 then "" else " (" ++ show i ++ " ignored)")
+    if cmdJson
+        then putStrLn . showIdeasJson $ showideas
+        else do
+            showItem <- if cmdColor then showANSI else return show
+            mapM_ (outStrLn . showItem) showideas
+            if null showideas then
+                when (cmdReports /= []) $ outStrLn "Skipping writing reports"
+             else
+                forM_ cmdReports $ \x -> do
+                    outStrLn $ "Writing report to " ++ x ++ " ..."
+                    writeReport cmdDataDir x showideas
+            outStrLn $
+                (let i = length showideas in if i == 0 then "No suggestions" else show i ++ " suggestion" ++ ['s'|i/=1]) ++
+                (let i = length hideideas in if i == 0 then "" else " (" ++ show i ++ " ignored)")
     return $ map Suggestion showideas
diff --git a/src/Hint/Duplicate.hs b/src/Hint/Duplicate.hs
--- a/src/Hint/Duplicate.hs
+++ b/src/Hint/Duplicate.hs
@@ -56,7 +56,7 @@
 add :: Ord val => pos -> [val] -> Dupe pos val -> Dupe pos val
 add pos [] d = d
 add pos (v:vs) (Dupe p mp) = Dupe p $ Map.insertWith f v (add pos vs $ Dupe pos Map.empty) mp
-    where f new old = add pos vs old
+    where f new = add pos vs
 
 
 duplicateOrdered :: Ord val => Int -> [[(SrcSpan,val)]] -> [(SrcSpan,SrcSpan,[val])]
diff --git a/src/Hint/Type.hs b/src/Hint/Type.hs
--- a/src/Hint/Type.hs
+++ b/src/Hint/Type.hs
@@ -21,6 +21,6 @@
     }
 
 instance Monoid Hint where
-    mempty = Hint (\_ -> []) (\_ _ -> []) (\_ _ _ -> []) (\_ -> [])
+    mempty = Hint (const []) (\_ _ -> []) (\_ _ _ -> []) (const [])
     mappend (Hint x1 x2 x3 x4) (Hint y1 y2 y3 y4) =
         Hint (\a -> x1 a ++ y1 a) (\a b -> x2 a b ++ y2 a b) (\a b c -> x3 a b c ++ y3 a b c) (\a -> x4 a ++ y4 a)
diff --git a/src/Idea.hs b/src/Idea.hs
--- a/src/Idea.hs
+++ b/src/Idea.hs
@@ -2,6 +2,7 @@
 
 module Idea(module Idea, Note(..), showNotes, Severity(..)) where
 
+import Data.List
 import HSE.All
 import Settings
 import Language.Haskell.HsColour.TTY
@@ -22,6 +23,27 @@
     }
     deriving (Eq,Ord)
 
+showIdeaJson :: Idea -> String
+showIdeaJson idea@Idea{ideaSpan=srcSpan@SrcSpan{..}, ..} = wrap . intercalate "," . map mkPair $
+    [("module", show ideaModule)
+    ,("decl", show ideaDecl)
+    ,("severity", show . show $ ideaSeverity)
+    ,("hint", show ideaHint)
+    ,("file", show srcSpanFilename)
+    ,("startLine", show srcSpanStartLine)
+    ,("startColumn", show srcSpanStartColumn)
+    ,("endLine", show srcSpanEndLine)
+    ,("endColumn", show srcSpanEndColumn)
+    ,("from", show ideaFrom)
+    ,("to", maybe "null" show ideaTo)
+    ,("note", show $ map (show . show) ideaNote)
+    ]
+  where
+    mkPair (k, v) = show k ++ ":" ++ v
+    wrap x = "{" ++ x ++ "}"
+
+showIdeasJson :: [Idea] -> String
+showIdeasJson ideas = "[" ++ intercalate "," (map showIdeaJson ideas) ++ "]"
 
 instance Show Idea where
     show = showEx id
diff --git a/src/Main.hs b/src/Main.hs
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -10,6 +10,6 @@
 main = do
     args <- getArgs
     errs <- hlint args
-    when (length errs > 0) $
+    unless (null errs) $
         exitWith $ ExitFailure 1
 
diff --git a/src/Report.hs b/src/Report.hs
--- a/src/Report.hs
+++ b/src/Report.hs
@@ -38,7 +38,7 @@
         getClass i = "hint" ++ f hints (hintName i) ++ " file" ++ f files (srcSpanFilename $ ideaSpan i)
             where f xs x = show $ fromJust $ findIndex ((==) x . fst) xs
 
-        list mode xs = zipWith f [0..] xs
+        list mode = zipWith f [0..]
             where
                 f i (name,n) = "<li><a id=" ++ show id ++ " href=\"javascript:show('" ++ id ++ "')\">" ++
                                escapeHTML name ++ " (" ++ show n ++ ")</a></li>"
diff --git a/src/Settings.hs b/src/Settings.hs
--- a/src/Settings.hs
+++ b/src/Settings.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE PatternGuards, ViewPatterns, RecordWildCards #-}
+{-# LANGUAGE PatternGuards, ViewPatterns #-}
 
 module Settings(
     Severity(..), Classify(..), HintRule(..), Note(..), showNotes, Setting(..),
