on master help sign in
Merge pull request #528 from bos/hlint

Hlinting

commit4861d65f63b9e9b7ef2fd5d39de2c00089c6fe38 authorAdam Bergmark <adam@bergmark.nl> dateSat 25 Mar 2017, 17:30 (10 years ago) parent13ee589e6db31e
27 files changed+93−72
.travis.yml+3 Data/Aeson/Encoding/Builder.hs+1−1 Data/Aeson/Internal/Time.hs+3−2 Data/Aeson/Parser/Internal.hs+2 Data/Aeson/TH.hs+7−8 Data/Aeson/Types/ToJSON.hs+4−3 HLint.hs+10 Makefile+2 benchmarks/AesonCompareAutoInstances.hs+2−2 benchmarks/AesonEncode.hs+2−3 benchmarks/AesonMap.hs+4−4 benchmarks/AesonParse.hs+1−2 benchmarks/AesonTuples.hs−2 benchmarks/Compare/JsonBench.hs+2−3 benchmarks/CompareWithJSON.hs+3−6 benchmarks/Dates.hs+8−8 benchmarks/ReadFile.hs+1−1 benchmarks/Typed/Common.hs+2 examples/Twitter.hs+3 examples/Twitter/Generic.hs−1 examples/Twitter/Manual.hs+4−1 pure/Data/Aeson/Parser/UnescapePure.hs+9−9 tests/Instances.hs+2−1 tests/Properties.hs+1−1 tests/SerializationFormatSpec.hs+3−3 tests/UnitTests.hs+9−11 travis/script.sh+5
.travis.yml+3
@@ -19,6 +19,9 @@ before_cache:
1919
2020matrix:
2121 include:
22+ - env: BUILD=hlint CABALVER=1.24 GHCVER=8.0.2
23+ compiler: ": #GHC 8.0.2"
24+ addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.2], sources: [hvr-ghc]}}
2225 - env: BUILD=stack CABALVER=1.24 GHCVER=8.0.2 STACK_YAML=stack-bench.yaml
2326 compiler: ": #GHC 8.0.2"
2427 addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.2], sources: [hvr-ghc]}}
Data/Aeson/Encoding/Builder.hs+1−1
@@ -292,7 +292,7 @@ encodeUtf8BuilderEscaped be =
292292 where
293293 iend = off + len
294294
295− outerLoop !i0 !br@(B.BufferRange op0 ope)
295+ outerLoop !i0 br@(B.BufferRange op0 ope)
296296 | i0 >= iend = k br
297297 | outRemaining > 0 = goPartial (i0 + min outRemaining inpRemaining)
298298 -- TODO: Use a loop with an integrated bound's check if outRemaining
Data/Aeson/Internal/Time.hs+3−2
@@ -20,14 +20,13 @@ module Data.Aeson.Internal.Time
2020import Prelude ()
2121import Prelude.Compat
2222
23−import Data.Fixed (Pico)
2423import Data.Int (Int64)
2524import Data.Time
2625import Unsafe.Coerce (unsafeCoerce)
2726
2827#if MIN_VERSION_base(4,7,0)
2928
30−import Data.Fixed (Fixed(MkFixed))
29+import Data.Fixed (Pico, Fixed(MkFixed))
3130
3231toPico :: Integer -> Pico
3332toPico = MkFixed
@@ -37,6 +36,8 @@ fromPico (MkFixed i) = i
3736
3837#else
3938
39+import Data.Fixed (Pico)
40+
4041toPico :: Integer -> Pico
4142toPico = unsafeCoerce
4243
Data/Aeson/Parser/Internal.hs+2
@@ -221,6 +221,8 @@ jstring_ = {-# SCC "jstring_" #-} do
221221 in Just (S a')
222222
223223data S = S Int#
224+-- This hint will no longer trigger once hlint > 1.9.41 is released.
225+{-# ANN S ("HLint: ignore Use newtype instead of data" :: String) #-}
224226#else
225227 startState = False
226228 go a c
Data/Aeson/TH.hs+7−8
@@ -1629,7 +1629,7 @@ buildTypeInstanceFromTys tyConName jc dataCxt varTysOrig isDataFamily = do
16291629 -- instance C (Fam [Char])
16301630 remainingTysOrigSubst :: [Type]
16311631 remainingTysOrigSubst =
1632− map (substNamesWithKindStar (union droppedKindVarNames kvNames'))
1632+ map (substNamesWithKindStar (droppedKindVarNames `union` kvNames'))
16331633 $ take remainingLength varTysOrig
16341634
16351635 remainingTysOrigSubst' :: [Type]
@@ -2118,7 +2118,7 @@ createKindChain :: Int -> Kind
21182118createKindChain = go starK
21192119 where
21202120 go :: Kind -> Int -> Kind
2121− go k !0 = k
2121+ go k 0 = k
21222122#if MIN_VERSION_template_haskell(2,8,0)
21232123 go k !n = go (AppT (AppT ArrowT StarT) k) (n - 1)
21242124#else
@@ -2245,7 +2245,7 @@ substNameWithKind :: Name -> Kind -> Type -> Type
22452245substNameWithKind n k = substKind (M.singleton n k)
22462246
22472247substNamesWithKindStar :: [Name] -> Type -> Type
2248−substNamesWithKindStar ns t = foldr' (flip substNameWithKind starK) t ns
2248+substNamesWithKindStar ns t = foldr' (`substNameWithKind` starK) t ns
22492249
22502250-------------------------------------------------------------------------------
22512251-- Error messages
@@ -2394,13 +2394,12 @@ data StarKindStatus = NotKindStar
23942394
23952395-- | Does a Type have kind * or k (for some kind variable k)?
23962396canRealizeKindStar :: Type -> StarKindStatus
2397−canRealizeKindStar t
2398− | hasKindStar t = KindStar
2399− | otherwise = case t of
2397+canRealizeKindStar t = case t of
2398+ _ | hasKindStar t -> KindStar
24002399#if MIN_VERSION_template_haskell(2,8,0)
2401− SigT _ (VarT k) -> IsKindVar k
2400+ SigT _ (VarT k) -> IsKindVar k
24022401#endif
2403− _ -> NotKindStar
2402+ _ -> NotKindStar
24042403
24052404-- | Returns 'Just' the kind variable 'Name' of a 'StarKindStatus' if it exists.
24062405-- Otherwise, returns 'Nothing'.
Data/Aeson/Types/ToJSON.hs+4−3
@@ -1,4 +1,3 @@
1−{-# LANGUAGE BangPatterns #-}
21{-# LANGUAGE CPP #-}
32{-# LANGUAGE DataKinds #-}
43{-# LANGUAGE DefaultSignatures #-}
@@ -132,6 +131,8 @@ import qualified Data.ByteString.Internal as S
132131import qualified Data.ByteString.Lazy.Internal as L
133132#endif
134133
134+{-# ANN module ("HLint: ignore Reduce duplication"::String) #-}
135+
135136toJSONPair :: (a -> Value) -> (b -> Value) -> (a, b) -> Value
136137toJSONPair a b = liftToJSON2 a (listValue a) b (listValue b)
137138{-# INLINE toJSONPair #-}
@@ -2827,8 +2828,8 @@ packChunks :: L.ByteString -> S.ByteString
28272828packChunks lbs =
28282829 S.unsafeCreate (fromIntegral $ L.length lbs) (copyChunks lbs)
28292830 where
2830− copyChunks !L.Empty !_pf = return ()
2831− copyChunks !(L.Chunk (S.PS fpbuf o l) lbs') !pf = do
2831+ copyChunks L.Empty _pf = return ()
2832+ copyChunks (L.Chunk (S.PS fpbuf o l) lbs') pf = do
28322833 withForeignPtr fpbuf $ \pbuf ->
28332834 copyBytes pf (pbuf `plusPtr` o) l
28342835 copyChunks lbs' (pf `plusPtr` l)
HLint.hsnew file+10
@@ -0,0 +1,10 @@
1+module HLint.HLint where
2+
3+import "hint" HLint.Default
4+import "hint" HLint.Builtin.All
5+import "hint" HLint.Dollar
6+
7+ignore "Avoid lambda"
8+ignore "Eta reduce"
9+ignore "Functor law"
10+ignore "Use >=>"
Makefilenew file+2
@@ -0,0 +1,2 @@
1+lint:
2+ hlint --cpp-include include/ --cpp-file .stack-work/dist/*/*Cabal-*/build/autogen/cabal_macros.h .
benchmarks/AesonCompareAutoInstances.hs+2−2
@@ -43,7 +43,7 @@ d :: T
4343d = Record
4444 { testOne = 1234.56789
4545 , testTwo = True
46− , testThree = Product "Hello World!" 'a' $
46+ , testThree = Product "Hello World!" 'a'
4747 Record
4848 { testOne = 9876.54321
4949 , testTwo = False
@@ -80,7 +80,7 @@ d' :: T'
8080d' = Record'
8181 { testOne' = 1234.56789
8282 , testTwo' = True
83− , testThree' = Product' "Hello World!" 'a' $
83+ , testThree' = Product' "Hello World!" 'a'
8484 Record'
8585 { testOne' = 9876.54321
8686 , testTwo' = False
benchmarks/AesonEncode.hs+2−3
@@ -7,7 +7,6 @@ import Prelude ()
77import Prelude.Compat
88
99import Control.DeepSeq
10−import Control.Exception
1110import Control.Monad
1211import Data.Aeson
1312import Data.Attoparsec.ByteString (IResult(..), parseWith)
@@ -25,7 +24,7 @@ main = do
2524 (c:a) -> (c,a)
2625 [] -> error "Unexpected empty list"
2726 let count = read cnt :: Int
28− forM_ args $ \arg -> bracket (openFile arg ReadMode) hClose $ \h -> do
27+ forM_ args $ \arg -> withFile arg ReadMode $ \h -> do
2928 putStrLn $ arg ++ ":"
3029 let refill = B.hGet h 16384
3130 result0 <- parseWith refill json =<< refill
@@ -35,7 +34,7 @@ main = do
3534 start <- getCurrentTime
3635 let loop !n r
3736 | n >= count = return ()
38− | otherwise = {-# SCC "loop" #-} do
37+ | otherwise = {-# SCC "loop" #-}
3938 rnf (encode r) `seq` loop (n+1) r
4039 loop 0 r0
4140 delta <- flip diffUTCTime start `fmap` getCurrentTime
benchmarks/AesonMap.hs+4−4
@@ -97,16 +97,16 @@ value1000 = value 1000
9797value10000 = value 10000
9898
9999encodedValue10 :: LBS.ByteString
100−encodedValue10 = B.encode $ value10
100+encodedValue10 = B.encode value10
101101
102102encodedValue100 :: LBS.ByteString
103−encodedValue100 = B.encode $ value100
103+encodedValue100 = B.encode value100
104104
105105encodedValue1000 :: LBS.ByteString
106−encodedValue1000 = B.encode $ value1000
106+encodedValue1000 = B.encode value1000
107107
108108encodedValue10000 :: LBS.ByteString
109−encodedValue10000 = B.encode $ value10000
109+encodedValue10000 = B.encode value10000
110110
111111-------------------------------------------------------------------------------
112112-- Helpers
benchmarks/AesonParse.hs+1−2
@@ -8,7 +8,6 @@ import Prelude ()
88import Prelude.Compat
99
1010import "aeson-benchmarks" Data.Aeson
11−import Control.Exception
1211import Control.Monad
1312import Data.Attoparsec.ByteString (IResult(..), parseWith)
1413import Data.Time.Clock
@@ -21,7 +20,7 @@ main = do
2120 (bs:cnt:args) <- getArgs
2221 let count = read cnt :: Int
2322 blkSize = read bs
24− forM_ args $ \arg -> bracket (openFile arg ReadMode) hClose $ \h -> do
23+ forM_ args $ \arg -> withFile arg ReadMode $ \h -> do
2524 putStrLn $ arg ++ ":"
2625 start <- getCurrentTime
2726 let loop !good !bad
benchmarks/AesonTuples.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
31module Main (main) where
42
53import Prelude ()
benchmarks/Compare/JsonBench.hs+2−3
@@ -3,7 +3,6 @@
33-- https://github.com/chadaustin/buffer-builder/blob/master/test.json
44
55{-# LANGUAGE BangPatterns #-}
6−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
76{-# LANGUAGE MagicHash #-}
87{-# LANGUAGE OverloadedStrings #-}
98{-# LANGUAGE RecordWildCards #-}
@@ -65,10 +64,10 @@ instance NFData Gender where rnf !_ = ()
6564instance NFData Fruit where rnf !_ = ()
6665
6766instance NFData Friend where
68− rnf Friend {..} = (rnf fId) `seq` (rnf fName) `seq` ()
67+ rnf Friend {..} = rnf fId `seq` rnf fName `seq` ()
6968
7069instance NFData User where
71− rnf User {..} = (rnf uId) `seq` (rnf uIndex) `seq` (rnf uGuid) `seq` (rnf uIsActive) `seq` (rnf uBalance) `seq` (rnf uPicture) `seq` (rnf uAge) `seq` (rnf uEyeColor) `seq` (rnf uName) `seq` (rnf uGender) `seq` (rnf uCompany) `seq` (rnf uEmail) `seq` (rnf uPhone) `seq` (rnf uAddress) `seq` (rnf uAbout) `seq` (rnf uRegistered) `seq` (rnf uLatitude) `seq` (rnf uLongitude) `seq` (rnf uTags) `seq` (rnf uFriends) `seq` (rnf uGreeting) `seq` (rnf uFavouriteFruit) `seq` ()
70+ rnf User {..} = rnf uId `seq` rnf uIndex `seq` rnf uGuid `seq` rnf uIsActive `seq` rnf uBalance `seq` rnf uPicture `seq` rnf uAge `seq` rnf uEyeColor `seq` rnf uName `seq` rnf uGender `seq` rnf uCompany `seq` rnf uEmail `seq` rnf uPhone `seq` rnf uAddress `seq` rnf uAbout `seq` rnf uRegistered `seq` rnf uLatitude `seq` rnf uLongitude `seq` rnf uTags `seq` rnf uFriends `seq` rnf uGreeting `seq` rnf uFavouriteFruit `seq` ()
7271
7372eyeColorTable :: [(Text, EyeColor)]
7473eyeColorTable = [("brown", Brown), ("green", Green), ("blue", Blue)]
benchmarks/CompareWithJSON.hs+3−6
@@ -9,6 +9,7 @@ import Blaze.ByteString.Builder (toLazyByteString)
99import Blaze.ByteString.Builder.Char.Utf8 (fromString)
1010import Control.DeepSeq (NFData(rnf))
1111import Criterion.Main
12+import Data.Maybe (fromMaybe)
1213import qualified Data.Aeson as A
1314import qualified Data.Aeson.Text as A
1415import qualified Data.ByteString.Lazy as BL
@@ -35,14 +36,10 @@ decodeJ s =
3536 J.Error _ -> error "fail to parse via JSON"
3637
3738decodeA :: BL.ByteString -> A.Value
38−decodeA s = case A.decode s of
39− Just v -> v
40− Nothing -> error "fail to parse via Aeson"
39+decodeA s = fromMaybe (error "fail to parse via Aeson") $ A.decode s
4140
4241decodeA' :: BL.ByteString -> A.Value
43−decodeA' s = case A.decode' s of
44− Just v -> v
45− Nothing -> error "fail to parse via Aeson"
42+decodeA' s = fromMaybe (error "fail to parse via Aeson") $ A.decode' s
4643
4744encodeJ :: J.JSValue -> BL.ByteString
4845encodeJ = toLazyByteString . fromString . J.encode
benchmarks/Dates.hs+8−8
@@ -22,22 +22,22 @@ main = do
2222 defaultMain [
2323 bgroup "decode" [
2424 bgroup "UTCTime" [
25− env file1 $ \ ~bs -> bench "whole" $ nf utcTime bs
26− , env file2 $ \ ~bs -> bench "fractional" $ nf utcTime bs
25+ env file1 $ \bs -> bench "whole" $ nf utcTime bs
26+ , env file2 $ \bs -> bench "fractional" $ nf utcTime bs
2727 ]
2828 , bgroup "ZonedTime" [
29− env file1 $ \ ~bs -> bench "whole" $ nf zTime bs
30− , env file2 $ \ ~bs -> bench "fractional" $ nf zTime bs
29+ env file1 $ \bs -> bench "whole" $ nf zTime bs
30+ , env file2 $ \bs -> bench "fractional" $ nf zTime bs
3131 ]
3232 ]
3333 , bgroup "encode" [
3434 bgroup "UTCTime" [
35− env (utcTime <$> file1) $ \ ~ts -> bench "whole" $ nf encode ts
36− , env (utcTime <$> file2) $ \ ~ts -> bench "fractional" $ nf encode ts
35+ env (utcTime <$> file1) $ \ts -> bench "whole" $ nf encode ts
36+ , env (utcTime <$> file2) $ \ts -> bench "fractional" $ nf encode ts
3737 ]
3838 , bgroup "ZonedTime" [
39− env (zTime <$> file1) $ \ ~ts -> bench "whole" $ nf encode ts
40− , env (zTime <$> file2) $ \ ~ts -> bench "fractional" $ nf encode ts
39+ env (zTime <$> file1) $ \ts -> bench "whole" $ nf encode ts
40+ , env (zTime <$> file2) $ \ts -> bench "fractional" $ nf encode ts
4141 ]
4242 ]
4343 ]
benchmarks/ReadFile.hs+1−1
@@ -20,7 +20,7 @@ import qualified Data.ByteString as B
2020main = do
2121 (cnt:args) <- getArgs
2222 let count = read cnt :: Int
23− forM_ args $ \arg -> bracket (openFile arg ReadMode) hClose $ \h -> do
23+ forM_ args $ \arg -> withFile arg ReadMode $ \h -> do
2424 putStrLn $ arg ++ ":"
2525 start <- getCurrentTime
2626 let loop !n
benchmarks/Typed/Common.hs+2
@@ -1,5 +1,7 @@
11{-# LANGUAGE CPP #-}
2+#ifdef HAS_BOTH_AESON_AND_BENCHMARKS
23{-# LANGUAGE PackageImports #-}
4+#endif
35
46{-# OPTIONS_GHC -fno-warn-unused-imports #-}
57
examples/Twitter.hs+3
@@ -29,6 +29,9 @@ import Data.Text (Text)
2929import GHC.Generics (Generic)
3030import Prelude hiding (id)
3131
32+{-# ANN module "Hlint: ignore Use camelCase" #-}
33+{-# ANN module "Hlint: ignore Use newtype instead of data" #-}
34+
3235data Metadata = Metadata {
3336 result_type :: Text
3437 } deriving (Eq, Show, Typeable, Data, Generic)
examples/Twitter/Generic.hs−1
@@ -1,6 +1,5 @@
11-- Use GHC generics to automatically generate good instances.
22{-# LANGUAGE CPP #-}
3−{-# LANGUAGE PackageImports #-}
43{-# OPTIONS_GHC -fno-warn-orphans #-}
54
65module Twitter.Generic
examples/Twitter/Manual.hs+4−1
@@ -1,11 +1,14 @@
11-- Manually write instances.
22
33{-# LANGUAGE CPP #-}
4−{-# LANGUAGE PackageImports #-}
54{-# LANGUAGE OverloadedStrings #-}
65{-# LANGUAGE RecordWildCards #-}
76{-# OPTIONS_GHC -fno-warn-orphans #-}
87
8+#ifdef HAS_BOTH_AESON_AND_BENCHMARKS
9+{-# LANGUAGE PackageImports #-}
10+#endif
11+
912module Twitter.Manual
1013 (
1114 Metadata(..)
pure/Data/Aeson/Parser/UnescapePure.hs+9−9
@@ -52,23 +52,23 @@ setByte1 point word = point .|. fromIntegral (word .&. 0x3f)
5252{-# INLINE setByte1 #-}
5353
5454setByte2 :: (Num a, Bits b, Bits a, Integral b) => a -> b -> a
55−setByte2 point word = point .|. ((fromIntegral $ word .&. 0x3f) `shiftL` 6)
55+setByte2 point word = point .|. (fromIntegral (word .&. 0x3f) `shiftL` 6)
5656{-# INLINE setByte2 #-}
5757
5858setByte2Top :: (Num a, Bits b, Bits a, Integral b) => a -> b -> a
59−setByte2Top point word = point .|. ((fromIntegral $ word .&. 0x1f) `shiftL` 6)
59+setByte2Top point word = point .|. (fromIntegral (word .&. 0x1f) `shiftL` 6)
6060{-# INLINE setByte2Top #-}
6161
6262setByte3 :: (Num a, Bits b, Bits a, Integral b) => a -> b -> a
63−setByte3 point word = point .|. ((fromIntegral $ word .&. 0x3f) `shiftL` 12)
63+setByte3 point word = point .|. (fromIntegral (word .&. 0x3f) `shiftL` 12)
6464{-# INLINE setByte3 #-}
6565
6666setByte3Top :: (Num a, Bits b, Bits a, Integral b) => a -> b -> a
67−setByte3Top point word = point .|. ((fromIntegral $ word .&. 0xf) `shiftL` 12)
67+setByte3Top point word = point .|. (fromIntegral (word .&. 0xf) `shiftL` 12)
6868{-# INLINE setByte3Top #-}
6969
7070setByte4 :: (Num a, Bits b, Bits a, Integral b) => a -> b -> a
71−setByte4 point word = point .|. ((fromIntegral $ word .&. 0x7) `shiftL` 18)
71+setByte4 point word = point .|. (fromIntegral (word .&. 0x7) `shiftL` 18)
7272{-# INLINE setByte4 #-}
7373
7474decode :: Utf -> Word32 -> Word8 -> (Utf, Word32)
@@ -207,12 +207,12 @@ unescapeText' bs = runText $ \done -> do
207207 let u = w' .|. w in
208208
209209 -- Get next state based on surrogates.
210− let st =
211− if u >= 0xd800 && u <= 0xdbff then -- High surrogate.
210+ let st
211+ | u >= 0xd800 && u <= 0xdbff = -- High surrogate.
212212 StateS0
213− else if u >= 0xdc00 && u <= 0xdfff then -- Low surrogate.
213+ | u >= 0xdc00 && u <= 0xdfff = -- Low surrogate.
214214 throwDecodeError
215− else
215+ | otherwise =
216216 StateNone
217217 in
218218 writeAndReturn dest pos u st
tests/Instances.hs+2−1
@@ -3,7 +3,6 @@
33{-# LANGUAGE FlexibleInstances #-}
44{-# LANGUAGE OverloadedStrings #-}
55{-# LANGUAGE RecordWildCards #-}
6−{-# LANGUAGE StandaloneDeriving #-}
76{-# OPTIONS_GHC -fno-warn-orphans #-}
87
98module Instances () where
@@ -45,6 +44,8 @@ import Data.Hashable.Time ()
4544import Numeric.Natural
4645#endif
4746
47+{-# ANN module ("HLint: ignore Use fewer imports"::String) #-}
48+
4849-- "System" types.
4950
5051instance Arbitrary DotNetTime where
tests/Properties.hs+1−1
@@ -235,7 +235,7 @@ tests = testGroup "properties" [
235235 [ testProperty "Identity Char" $ roundTripEq (undefined :: I Int)
236236
237237 , testProperty "Identity Char" $ roundTripEq (undefined :: I Char)
238− , testProperty "Identity [Char]" $ roundTripEq (undefined :: I [Char])
238+ , testProperty "Identity [Char]" $ roundTripEq (undefined :: I String)
239239 , testProperty "[Identity Char]" $ roundTripEq (undefined :: [I Char])
240240
241241 , testProperty "Compose I I Int" $ roundTripEq (undefined :: LogScaled (Compose I I Int))
tests/SerializationFormatSpec.hs+3−3
@@ -86,7 +86,7 @@ jsonExamples =
8686 , Example "Map Int Int" "{\"0\":1,\"2\":3}" (M.fromList [(0,1),(2,3)] :: M.Map Int Int)
8787 , Example "Map (Tagged Int Int) Int" "{\"0\":1,\"2\":3}" (M.fromList [(Tagged 0,1),(Tagged 2,3)] :: M.Map (Tagged Int Int) Int)
8888 , Example "Map [Int] Int" "[[[0],1],[[2],3]]" (M.fromList [([0],1),([2],3)] :: M.Map [Int] Int)
89− , Example "Map [Char] Int" "{\"ab\":1,\"cd\":3}" (M.fromList [("ab",1),("cd",3)] :: M.Map [Char] Int)
89+ , Example "Map [Char] Int" "{\"ab\":1,\"cd\":3}" (M.fromList [("ab",1),("cd",3)] :: M.Map String Int)
9090 , Example "Map [I Char] Int" "{\"ab\":1,\"cd\":3}" (M.fromList [(map pure "ab",1),(map pure "cd",3)] :: M.Map [I Char] Int)
9191
9292 , Example "nan :: Double" "null" (Approx $ 0/0 :: Approx Double)
@@ -197,9 +197,9 @@ jsonDecodingExamples :: [Example]
197197jsonDecodingExamples = [
198198 -- Maybe serialising is lossy
199199 -- https://github.com/bos/aeson/issues/376
200− MaybeExample "Nothing" "null" (Just $ Nothing :: Maybe (Maybe Int))
200+ MaybeExample "Nothing" "null" (Just Nothing :: Maybe (Maybe Int))
201201 , MaybeExample "Just" "1" (Just $ Just 1 :: Maybe (Maybe Int))
202− , MaybeExample "Just Nothing" "null" (Just $ Nothing :: Maybe (Maybe (Maybe Int)))
202+ , MaybeExample "Just Nothing" "null" (Just Nothing :: Maybe (Maybe (Maybe Int)))
203203 -- Integral values are truncated, and overflowed
204204 -- https://github.com/bos/aeson/issues/317
205205 , MaybeExample "Word8 3" "3" (Just 3 :: Maybe Word8)
tests/UnitTests.hs+9−11
@@ -74,14 +74,14 @@ tests = testGroup "unit" [
7474 assertEqual "" "camel_api_case" (camelTo2 '_' "CamelAPICase")
7575 ]
7676 , testGroup "encoding" [
77− testCase "goodProducer" $ goodProducer
77+ testCase "goodProducer" goodProducer
7878 ]
7979 , testGroup "utctime" [
80− testCase "good" $ utcTimeGood
81− , testCase "bad" $ utcTimeBad
80+ testCase "good" utcTimeGood
81+ , testCase "bad" utcTimeBad
8282 ]
8383 , testGroup "formatError" [
84− testCase "example 1" $ formatErrorExample
84+ testCase "example 1" formatErrorExample
8585 ]
8686 , testGroup ".:, .:?, .:!" $ fmap (testCase "-") dotColonMark
8787 , testGroup "JSONPath" $ fmap (testCase "-") jsonPath
@@ -187,11 +187,9 @@ utcTimeGood = do
187187 where
188188 parseWithRead :: String -> LT.Text -> UTCTime
189189 parseWithRead f s =
190− case parseTime defaultTimeLocale f . LT.unpack $ s of
191− Nothing -> error "parseTime input malformed"
192− Just t -> t
190+ fromMaybe (error "parseTime input malformed") . parseTime defaultTimeLocale f . LT.unpack $ s
193191 parseWithAeson :: LT.Text -> Maybe UTCTime
194− parseWithAeson s = decode . LT.encodeUtf8 $ (LT.concat ["\"", s, "\""])
192+ parseWithAeson s = decode . LT.encodeUtf8 $ LT.concat ["\"", s, "\""]
195193
196194-- Test that a few non-timezone qualified timestamp formats get
197195-- rejected if decoding to UTCTime.
@@ -207,7 +205,7 @@ utcTimeBad = do
207205 verifyFailParse "2015-01-03 12:13.000Z" -- decimal at the end, but no seconds
208206 where
209207 verifyFailParse (s :: LT.Text) =
210− let (dec :: Maybe UTCTime) = decode . LT.encodeUtf8 $ (LT.concat ["\"", s, "\""]) in
208+ let (dec :: Maybe UTCTime) = decode . LT.encodeUtf8 $ LT.concat ["\"", s, "\""] in
211209 assertEqual "verify failure" Nothing dec
212210
213211-- Non identifier keys should be escaped & enclosed in brackets
@@ -235,11 +233,11 @@ dotColonMark = [
235233 , assertEqual ".: 42" (Just (T1 (Just 42))) (decode ex2 :: Maybe T1)
236234 , assertEqual ".: null" (Just (T1 Nothing)) (decode ex3 :: Maybe T1)
237235
238− , assertEqual ".:? not-present" (Just (T2 (Nothing))) (decode ex1 :: Maybe T2)
236+ , assertEqual ".:? not-present" (Just (T2 Nothing)) (decode ex1 :: Maybe T2)
239237 , assertEqual ".:? 42" (Just (T2 (Just 42))) (decode ex2 :: Maybe T2)
240238 , assertEqual ".:? null" (Just (T2 Nothing)) (decode ex3 :: Maybe T2)
241239
242− , assertEqual ".:! not-present" (Just (T3 (Nothing))) (decode ex1 :: Maybe T3)
240+ , assertEqual ".:! not-present" (Just (T3 Nothing)) (decode ex1 :: Maybe T3)
243241 , assertEqual ".:! 42" (Just (T3 (Just 42))) (decode ex2 :: Maybe T3)
244242 , assertEqual ".:! null" Nothing (decode ex3 :: Maybe T3)
245243 ]
travis/script.sh+5
@@ -19,4 +19,9 @@ case $BUILD in
1919 SRC_TGZ=$(cabal info . | awk '{print $2;exit}').tar.gz &&
2020 (cd dist && cabal install --force-reinstalls "$SRC_TGZ")
2121 ;;
22+ hlint)
23+ stack build --fast aeson --stack-yaml stack-lts8.yaml --system-ghc --no-terminal
24+ stack install hlint --resolver lts-8 --system-ghc --no-terminal
25+ make lint
26+ ;;
2227esac