derulo 1.0.10 → 2.0.0.1
raw patch · 9 files changed
+958/−781 lines, 9 filesdep ~basePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base
API changes (from Hackage documentation)
Files
- CHANGELOG.markdown +4/−0
- LICENSE.markdown +1/−1
- derulo.cabal +39/−14
- source/executable/Main.hs +5/−0
- source/library/Derulo.hs +383/−0
- source/test-suite/Main.hs +526/−0
- src/exe/Main.hs +0/−5
- src/lib/Derulo.hs +0/−408
- src/test/Main.hs +0/−353
+ CHANGELOG.markdown view
@@ -0,0 +1,4 @@+# Change log++Derulo follows the [Package Versioning Policy](https://pvp.haskell.org).+You can find release notes [on GitHub](https://github.com/tfausak/derulo/releases).
LICENSE.markdown view
@@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021 Taylor Fausak+Copyright (c) 2022 Taylor Fausak Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal
derulo.cabal view
@@ -1,14 +1,14 @@-cabal-version: >= 1.10+cabal-version: 2.2 name: derulo-version: 1.0.10+version: 2.0.0.1 synopsis: Parse and render JSON simply. description: Derulo parses and renders JSON simply. build-type: Simple category: JSON-extra-source-files: README.markdown+extra-source-files: CHANGELOG.markdown README.markdown license-file: LICENSE.markdown license: MIT maintainer: Taylor Fausak@@ -17,36 +17,61 @@ location: https://github.com/tfausak/derulo type: git -library+flag pedantic+ default: False+ description: Enables @-Werror@, which turns warnings into errors.+ manual: True++common library build-depends:- base >= 4.13.0 && < 4.16+ base >= 4.13.0 && < 4.17 default-language: Haskell2010- exposed-modules: Derulo ghc-options: -Weverything+ -Wno-all-missed-specialisations -Wno-implicit-prelude -Wno-missing-deriving-strategies -Wno-missing-exported-signatures -Wno-safe- hs-source-dirs: src/lib + if flag(pedantic)+ ghc-options: -Werror+ if impl(ghc >= 8.10) ghc-options: -Wno-missing-safe-haskell-mode -Wno-prepositive-qualified-module + if impl(ghc >= 9.2)+ ghc-options:+ -Wno-missing-kind-signatures++common executable+ import: library++ build-depends: derulo+ ghc-options:+ -rtsopts+ -threaded+ -Wno-unused-packages++library+ import: library++ exposed-modules: Derulo+ hs-source-dirs: source/library+ executable derulo- build-depends: base, derulo- default-language: Haskell2010- hs-source-dirs: src/exe+ import: executable++ hs-source-dirs: source/executable main-is: Main.hs test-suite test+ import: executable+ build-depends:- base -any- , derulo -any , HUnit >= 1.6.1 && < 1.7- default-language: Haskell2010- hs-source-dirs: src/test+ hs-source-dirs: source/test-suite main-is: Main.hs type: exitcode-stdio-1.0
+ source/executable/Main.hs view
@@ -0,0 +1,5 @@+import qualified Data.Maybe as Maybe+import qualified Derulo++main :: IO ()+main = interact (Derulo.showJSON . Maybe.fromJust . Derulo.readJSON)
+ source/library/Derulo.hs view
@@ -0,0 +1,383 @@+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE DeriveGeneric #-}++-- | Derulo parses and renders JSON simply. It aims to provide an RFC 7159+-- compliant parser and renderer without incurring any dependencies. It is+-- intended to be used either for learning or in situations where dependencies+-- are unwanted. In normal usage, prefer a faster, more robust library like+-- [Aeson](https://hackage.haskell.org/package/aeson).+--+-- Derulo does not export any identifiers that conflict with the prelude and+-- can be imported unqualified.+--+-- >>> import Derulo+--+-- Use 'readJSON' to parse a 'String' into a 'JSON' value.+--+-- >>> readJSON " null "+-- Just Null+--+-- Use 'showJSON' to render a 'JSON' value as a 'String'.+--+-- >>> showJSON Null+-- "null"+module Derulo+ ( JSON(..)+ , readJSON+ , showJSON+ ) where++import qualified Control.Monad as Monad+import qualified Data.Data as Data+import qualified Data.Functor as Functor+import qualified Data.List as List+import qualified Data.Maybe as Maybe+import qualified GHC.Generics as Generics+import qualified Text.ParserCombinators.ReadP as ReadP++-- * Types+-- | A JSON value as described by RFC 7159.+data JSON+ = Null+ | Boolean Bool+ | Number Integer+ Integer+ | String String+ | Array [JSON]+ | Object [(String, JSON)]+ deriving (Data.Data, Eq, Generics.Generic, Ord, Read, Show)++-- * Parsing+-- | Parses a string as JSON.+readJSON :: String -> Maybe JSON+readJSON = runParser pJSON++pJSON :: ReadP.ReadP JSON+pJSON = do+ pWhitespaces+ value <- pValue+ ReadP.eof+ pure value++pValue :: ReadP.ReadP JSON+pValue = ReadP.choice [pNull, pBoolean, pNumber, pString, pArray, pObject]++pNull :: ReadP.ReadP JSON+pNull = do+ pSymbol "null"+ pure Null++pBoolean :: ReadP.ReadP JSON+pBoolean = pTrue ReadP.+++ pFalse++pTrue :: ReadP.ReadP JSON+pTrue = do+ pSymbol "true"+ pure (Boolean True)++pFalse :: ReadP.ReadP JSON+pFalse = do+ pSymbol "false"+ pure (Boolean False)++pNumber :: ReadP.ReadP JSON+pNumber = do+ integer <- pInteger+ (fraction, precision) <- ReadP.option (0, 0) pFraction+ power <- ReadP.option 0 pPower+ pWhitespaces+ let mantissa = integer * 10 ^ precision + negateIf (integer <= 0) fraction+ let magnitude = power - precision+ pure (Number mantissa magnitude)++pInteger :: ReadP.ReadP Integer+pInteger = pZero ReadP.+++ pNonZero++pZero :: ReadP.ReadP Integer+pZero = do+ ReadP.optional (ReadP.char '-')+ Functor.void (ReadP.char '0')+ pure 0++pNonZero :: ReadP.ReadP Integer+pNonZero = do+ sign <- ReadP.option '+' (ReadP.char '-')+ first <- ReadP.satisfy isNonZeroDigit+ rest <- ReadP.munch isDecimalDigit+ case fromDecimal (first : rest) of+ Nothing -> ReadP.pfail+ Just nonZero -> pure (negateIf (sign == '-') nonZero)++pFraction :: ReadP.ReadP (Integer, Integer)+pFraction = do+ Functor.void (ReadP.char '.')+ digits <- ReadP.munch1 isDecimalDigit+ case fromDecimal digits of+ Nothing -> ReadP.pfail+ Just fraction -> pure (fraction, List.genericLength digits)++pPower :: ReadP.ReadP Integer+pPower = do+ Functor.void (ReadP.char 'E' ReadP.+++ ReadP.char 'e')+ sign <- ReadP.option '+' (ReadP.char '+' ReadP.+++ ReadP.char '-')+ digits <- ReadP.munch1 isDecimalDigit+ case fromDecimal digits of+ Nothing -> ReadP.pfail+ Just magnitude -> pure (negateIf (sign == '-') magnitude)++pString :: ReadP.ReadP JSON+pString = do+ string <- ReadP.between+ (ReadP.char '"')+ (ReadP.char '"')+ (do+ characters <- ReadP.many pCharacter+ pure (String characters)+ )+ pWhitespaces+ pure string++pCharacter :: ReadP.ReadP Char+pCharacter = pLiteral ReadP.+++ pEscape++pLiteral :: ReadP.ReadP Char+pLiteral = ReadP.satisfy isLiteral++pEscape :: ReadP.ReadP Char+pEscape = do+ Functor.void (ReadP.char '\\')+ escape <- ReadP.get+ case escape of+ '"' -> pure '"'+ '/' -> pure '/'+ '\\' -> pure '\\'+ 'b' -> pure '\b'+ 'f' -> pure '\f'+ 'n' -> pure '\n'+ 'r' -> pure '\r'+ 't' -> pure '\t'+ 'u' -> do+ digits <- ReadP.count 4 (ReadP.satisfy isHexadecimalDigit)+ case fromHexadecimal digits of+ Nothing -> ReadP.pfail+ Just point -> pure (toEnum (fromIntegral point))+ _ -> ReadP.pfail++pArray :: ReadP.ReadP JSON+pArray = ReadP.between+ (pSymbol "[")+ (pSymbol "]")+ (do+ values <- ReadP.sepBy pValue (pSymbol ",")+ pure (Array values)+ )++pObject :: ReadP.ReadP JSON+pObject = ReadP.between+ (pSymbol "{")+ (pSymbol "}")+ (do+ pairs <- ReadP.sepBy pPair (pSymbol ",")+ pure (Object pairs)+ )++pPair :: ReadP.ReadP (String, JSON)+pPair = do+ String key <- pString+ pSymbol ":"+ value <- pValue+ pure (key, value)++-- * Rendering+-- | Renders JSON as a string.+showJSON :: JSON -> String+showJSON json = sJSON json ""++sJSON :: JSON -> ShowS+sJSON json = case json of+ Null -> sNull+ Boolean boolean -> sBoolean boolean+ Number mantissa magnitude -> sNumber mantissa magnitude+ String string -> sString string+ Array array -> sArray array+ Object object -> sObject object++sNull :: ShowS+sNull = showString "null"++sBoolean :: Bool -> ShowS+sBoolean boolean = if boolean then sTrue else sFalse++sTrue :: ShowS+sTrue = showString "true"++sFalse :: ShowS+sFalse = showString "false"++sNumber :: Integer -> Integer -> ShowS+sNumber mantissa magnitude = shows mantissa . showChar 'e' . shows magnitude++sString :: String -> ShowS+sString = sSeparatedBetween (showChar '"') (showChar '"') id sCharacter++sCharacter :: Char -> ShowS+sCharacter character = case character of+ '"' -> showString "\\\""+ '\\' -> showString "\\\\"+ '\b' -> showString "\\b"+ '\f' -> showString "\\f"+ '\n' -> showString "\\n"+ '\r' -> showString "\\r"+ '\t' -> showString "\\t"+ _ -> if isControl character+ then showString "\\u" . showString+ (padLeft 4 '0' (toHexadecimal (fromIntegral (fromEnum character))))+ else showChar character++sArray :: [JSON] -> ShowS+sArray = sSeparatedBetween (showChar '[') (showChar ']') (showChar ',') sJSON++sObject :: [(String, JSON)] -> ShowS+sObject = sSeparatedBetween (showChar '{') (showChar '}') (showChar ',') sPair++sPair :: (String, JSON) -> ShowS+sPair (key, value) = sString key . showChar ':' . sJSON value++-- * Helpers+fromBase :: Integer -> (Char -> Maybe Integer) -> String -> Maybe Integer+fromBase b f = Monad.foldM+ (\n c -> do+ d <- f c+ pure (b * n + d)+ )+ 0++fromDecimal :: String -> Maybe Integer+fromDecimal = fromBase 10 fromDecimalDigit++fromDecimalDigit :: Char -> Maybe Integer+fromDecimalDigit c = case c of+ '0' -> Just 0+ '1' -> Just 1+ '2' -> Just 2+ '3' -> Just 3+ '4' -> Just 4+ '5' -> Just 5+ '6' -> Just 6+ '7' -> Just 7+ '8' -> Just 8+ '9' -> Just 9+ _ -> Nothing++fromHexadecimal :: String -> Maybe Integer+fromHexadecimal = fromBase 16 fromHexadecimalDigit++fromHexadecimalDigit :: Char -> Maybe Integer+fromHexadecimalDigit c = case c of+ 'A' -> Just 10+ 'B' -> Just 11+ 'C' -> Just 12+ 'D' -> Just 13+ 'E' -> Just 14+ 'F' -> Just 15+ 'a' -> Just 10+ 'b' -> Just 11+ 'c' -> Just 12+ 'd' -> Just 13+ 'e' -> Just 14+ 'f' -> Just 15+ _ -> fromDecimalDigit c++isControl :: Char -> Bool+isControl c = '\x00' <= c && c <= '\x1f'++isDecimalDigit :: Char -> Bool+isDecimalDigit c = '0' <= c && c <= '9'++isHexadecimalDigit :: Char -> Bool+isHexadecimalDigit c =+ isDecimalDigit c || 'A' <= c && c <= 'F' || 'a' <= c && c <= 'f'++isLiteral :: Char -> Bool+isLiteral c = not (c == '"' || c == '\\' || isControl c)++isNonZeroDigit :: Char -> Bool+isNonZeroDigit c = '1' <= c && c <= '9'++isWhitespace :: Char -> Bool+isWhitespace c = c == '\t' || c == '\n' || c == '\r' || c == ' '++negateIf :: Bool -> Integer -> Integer+negateIf p n = if p then negate n else n++pSymbol :: String -> ReadP.ReadP ()+pSymbol s = do+ Functor.void (ReadP.string s)+ pWhitespaces++pWhitespaces :: ReadP.ReadP ()+pWhitespaces = Functor.void (ReadP.munch isWhitespace)++padLeft :: Integer -> a -> [a] -> [a]+padLeft n x ys = reverse (padRight n x (reverse ys))++padRight :: Integer -> a -> [a] -> [a]+padRight n x ys = if n <= 0+ then ys+ else case ys of+ [] -> x : padRight (n - 1) x ys+ y : zs -> y : padRight (n - 1) x zs++runParser :: ReadP.ReadP a -> String -> Maybe a+runParser p s = Maybe.listToMaybe+ (Maybe.mapMaybe+ (\(x, t) -> if null t then Just x else Nothing)+ (ReadP.readP_to_S p s)+ )++sBetween :: ShowS -> ShowS -> (anything -> ShowS) -> anything -> ShowS+sBetween left right render it = left . render it . right++sSeparated :: ShowS -> (element -> ShowS) -> [element] -> ShowS+sSeparated separator render elements = case elements of+ [] -> id+ [element] -> render element+ element : rest ->+ render element . separator . sSeparated separator render rest++sSeparatedBetween+ :: ShowS -> ShowS -> ShowS -> (element -> ShowS) -> [element] -> ShowS+sSeparatedBetween left right separator render =+ sBetween left right (sSeparated separator render)++toBase :: Integer -> (Integer -> Maybe Char) -> Integer -> String+toBase b f n =+ if n == 0 then [Maybe.fromJust (f n)] else reverse (toBase' b f n)++toBase' :: Integer -> (Integer -> Maybe Char) -> Integer -> String+toBase' b f n = case quotRem n b of+ (0, 0) -> ""+ (q, r) -> Maybe.fromJust (f r) : toBase' b f q++toHexadecimal :: Integer -> String+toHexadecimal = toBase 16 toHexadecimalDigit++toHexadecimalDigit :: Integer -> Maybe Char+toHexadecimalDigit n = case n of+ 0 -> Just '0'+ 1 -> Just '1'+ 2 -> Just '2'+ 3 -> Just '3'+ 4 -> Just '4'+ 5 -> Just '5'+ 6 -> Just '6'+ 7 -> Just '7'+ 8 -> Just '8'+ 9 -> Just '9'+ 10 -> Just 'a'+ 11 -> Just 'b'+ 12 -> Just 'c'+ 13 -> Just 'd'+ 14 -> Just 'e'+ 15 -> Just 'f'+ _ -> Nothing
+ source/test-suite/Main.hs view
@@ -0,0 +1,526 @@+import qualified Control.Monad as Monad+import qualified Derulo+import qualified System.Exit as Exit+import qualified Test.HUnit as Test++main :: IO ()+main = do+ counts <- Test.runTestTT $ Test.TestList+ [ Derulo.readJSON " null " Test.~?= Just Derulo.Null+ , Derulo.showJSON Derulo.Null Test.~?= "null"+ , Derulo.readJSON "null" Test.~?= Just Derulo.Null+ , Derulo.readJSON "true" Test.~?= Just (Derulo.Boolean True)+ , Derulo.readJSON "false" Test.~?= Just (Derulo.Boolean False)+ , Derulo.readJSON "0e0" Test.~?= Just (Derulo.Number 0 0)+ , Derulo.readJSON "12e34" Test.~?= Just (Derulo.Number 12 34)+ , Derulo.readJSON "-12e-34" Test.~?= Just (Derulo.Number (-12) (-34))+ , Derulo.readJSON "\"\"" Test.~?= Just (Derulo.String "")+ , Derulo.readJSON "\"js\"" Test.~?= Just (Derulo.String "js")+ , Derulo.readJSON "\"\\\"\\\\\\b\\f\\n\\r\\t\""+ Test.~?= Just (Derulo.String "\"\\\b\f\n\r\t")+ , Derulo.readJSON "\"\\u001f\"" Test.~?= Just (Derulo.String "\x1f")+ , Derulo.readJSON "[]" Test.~?= Just (Derulo.Array [])+ , Derulo.readJSON "[null]" Test.~?= Just (Derulo.Array [Derulo.Null])+ , Derulo.readJSON "[true,false]"+ Test.~?= Just (Derulo.Array [Derulo.Boolean True, Derulo.Boolean False])+ , Derulo.readJSON "{}" Test.~?= Just (Derulo.Object [])+ , Derulo.readJSON "{\"\":null}"+ Test.~?= Just (Derulo.Object [("", Derulo.Null)])+ , Derulo.readJSON "{\"t\":true,\"f\":false}" Test.~?= Just+ (Derulo.Object [("t", Derulo.Boolean True), ("f", Derulo.Boolean False)])+ , Derulo.showJSON Derulo.Null Test.~?= "null"+ , Derulo.showJSON (Derulo.Boolean True) Test.~?= "true"+ , Derulo.showJSON (Derulo.Boolean False) Test.~?= "false"+ , Derulo.showJSON (Derulo.Number 0 0) Test.~?= "0e0"+ , Derulo.showJSON (Derulo.Number 12 34) Test.~?= "12e34"+ , Derulo.showJSON (Derulo.Number (-12) (-34)) Test.~?= "-12e-34"+ , Derulo.showJSON (Derulo.String "") Test.~?= "\"\""+ , Derulo.showJSON (Derulo.String "js") Test.~?= "\"js\""+ , Derulo.showJSON (Derulo.String "\"\\\b\f\n\r\t")+ Test.~?= "\"\\\"\\\\\\b\\f\\n\\r\\t\""+ , Derulo.showJSON (Derulo.String "\x1f") Test.~?= "\"\\u001f\""+ , Derulo.showJSON (Derulo.Array []) Test.~?= "[]"+ , Derulo.showJSON (Derulo.Array [Derulo.Null]) Test.~?= "[null]"+ , Derulo.showJSON+ (Derulo.Array [Derulo.Boolean True, Derulo.Boolean False])+ Test.~?= "[true,false]"+ , Derulo.showJSON (Derulo.Object []) Test.~?= "{}"+ , Derulo.showJSON (Derulo.Object [("", Derulo.Null)])+ Test.~?= "{\"\":null}"+ , Derulo.showJSON+ (Derulo.Object+ [("t", Derulo.Boolean True), ("f", Derulo.Boolean False)]+ )+ Test.~?= "{\"t\":true,\"f\":false}"+ , Derulo.readJSON "[123.456e-789]"+ Test.~?= Just (Derulo.Array [Derulo.Number 123456 (-792)])+ , Derulo.readJSON+ "[0.4e00669999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999969999999006]"+ Test.~?= Just+ (Derulo.Array+ [ Derulo.Number+ (-4)+ 669999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999969999999005+ ]+ )+ , Derulo.readJSON "[-1e+9999]"+ Test.~?= Just (Derulo.Array [Derulo.Number (-1) 9999])+ , Derulo.readJSON "[1.5e+9999]"+ Test.~?= Just (Derulo.Array [Derulo.Number 15 9998])+ , Derulo.readJSON "[-123123e100000]"+ Test.~?= Just (Derulo.Array [Derulo.Number (-123123) 100000])+ , Derulo.readJSON "[123123e100000]"+ Test.~?= Just (Derulo.Array [Derulo.Number 123123 100000])+ , Derulo.readJSON "[123e-10000000]"+ Test.~?= Just (Derulo.Array [Derulo.Number 123 (-10000000)])+ , Derulo.readJSON "[-123123123123123123123123123123]" Test.~?= Just+ (Derulo.Array [Derulo.Number (-123123123123123123123123123123) 0])+ , Derulo.readJSON "[100000000000000000000]"+ Test.~?= Just (Derulo.Array [Derulo.Number 100000000000000000000 0])+ , Derulo.readJSON "[-237462374673276894279832749832423479823246327846]"+ Test.~?= Just+ (Derulo.Array+ [ Derulo.Number+ (-237462374673276894279832749832423479823246327846)+ 0+ ]+ )+ , Derulo.readJSON "{\"\\uDFAA\":0}"+ Test.~?= Just (Derulo.Object [("\57258", Derulo.Number 0 0)])+ , Derulo.readJSON "[\"\\uDADA\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\56026"])+ , Derulo.readJSON "[\"\\uD888\\u1234\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\55432\4660"])+ , Derulo.readJSON "[\"\\uD800\\n\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\55296\n"])+ , Derulo.readJSON "[\"\\uDd1ea\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\56606a"])+ , Derulo.readJSON "[\"\\uD800\\uD800\\n\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\55296\55296\n"])+ , Derulo.readJSON "[\"\\ud800\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\55296"])+ , Derulo.readJSON "[\"\\ud800abc\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\55296abc"])+ , Derulo.readJSON "[\"\\uDd1e\\uD834\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\56606\55348"])+ , Derulo.readJSON "[\"\\uDFAA\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\57258"])+ , Derulo.readJSON "\65279{}" Test.~?= Nothing+ , Derulo.readJSON "[1 true]" Test.~?= Nothing+ , Derulo.readJSON "[\"\": 1]" Test.~?= Nothing+ , Derulo.readJSON "[\"\"]," Test.~?= Nothing+ , Derulo.readJSON "[,1]" Test.~?= Nothing+ , Derulo.readJSON "[1,,2]" Test.~?= Nothing+ , Derulo.readJSON "[\"x\",,]" Test.~?= Nothing+ , Derulo.readJSON "[\"x\"]]" Test.~?= Nothing+ , Derulo.readJSON "[\"\",]" Test.~?= Nothing+ , Derulo.readJSON "[\"x\"" Test.~?= Nothing+ , Derulo.readJSON "[x" Test.~?= Nothing+ , Derulo.readJSON "[3[4]]" Test.~?= Nothing+ , Derulo.readJSON "[1:2]" Test.~?= Nothing+ , Derulo.readJSON "[,]" Test.~?= Nothing+ , Derulo.readJSON "[-]" Test.~?= Nothing+ , Derulo.readJSON "[ , \"\"]" Test.~?= Nothing+ , Derulo.readJSON "[\"a\",\n4\n,1," Test.~?= Nothing+ , Derulo.readJSON "[1,]" Test.~?= Nothing+ , Derulo.readJSON "[1,,]" Test.~?= Nothing+ , Derulo.readJSON "[\"\va\"\\f]" Test.~?= Nothing+ , Derulo.readJSON "[*]" Test.~?= Nothing+ , Derulo.readJSON "[\"\"" Test.~?= Nothing+ , Derulo.readJSON "[1," Test.~?= Nothing+ , Derulo.readJSON "[1,\n1\n,1" Test.~?= Nothing+ , Derulo.readJSON "[{}" Test.~?= Nothing+ , Derulo.readJSON "[fals]" Test.~?= Nothing+ , Derulo.readJSON "[nul]" Test.~?= Nothing+ , Derulo.readJSON "[tru]" Test.~?= Nothing+ , Derulo.readJSON "123\NUL" Test.~?= Nothing+ , Derulo.readJSON "[++1234]" Test.~?= Nothing+ , Derulo.readJSON "[+1]" Test.~?= Nothing+ , Derulo.readJSON "[+Inf]" Test.~?= Nothing+ , Derulo.readJSON "[-01]" Test.~?= Nothing+ , Derulo.readJSON "[-1.0.]" Test.~?= Nothing+ , Derulo.readJSON "[-2.]" Test.~?= Nothing+ , Derulo.readJSON "[-NaN]" Test.~?= Nothing+ , Derulo.readJSON "[.-1]" Test.~?= Nothing+ , Derulo.readJSON "[.2e-3]" Test.~?= Nothing+ , Derulo.readJSON "[0.1.2]" Test.~?= Nothing+ , Derulo.readJSON "[0.3e+]" Test.~?= Nothing+ , Derulo.readJSON "[0.3e]" Test.~?= Nothing+ , Derulo.readJSON "[0.e1]" Test.~?= Nothing+ , Derulo.readJSON "[0E+]" Test.~?= Nothing+ , Derulo.readJSON "[0E]" Test.~?= Nothing+ , Derulo.readJSON "[0e+]" Test.~?= Nothing+ , Derulo.readJSON "[0e]" Test.~?= Nothing+ , Derulo.readJSON "[1.0e+]" Test.~?= Nothing+ , Derulo.readJSON "[1.0e-]" Test.~?= Nothing+ , Derulo.readJSON "[1.0e]" Test.~?= Nothing+ , Derulo.readJSON "[1 000.0]" Test.~?= Nothing+ , Derulo.readJSON "[1eE2]" Test.~?= Nothing+ , Derulo.readJSON "[2.e+3]" Test.~?= Nothing+ , Derulo.readJSON "[2.e-3]" Test.~?= Nothing+ , Derulo.readJSON "[2.e3]" Test.~?= Nothing+ , Derulo.readJSON "[9.e+]" Test.~?= Nothing+ , Derulo.readJSON "[Inf]" Test.~?= Nothing+ , Derulo.readJSON "[NaN]" Test.~?= Nothing+ , Derulo.readJSON "[\65297]" Test.~?= Nothing+ , Derulo.readJSON "[1+2]" Test.~?= Nothing+ , Derulo.readJSON "[0x1]" Test.~?= Nothing+ , Derulo.readJSON "[0x42]" Test.~?= Nothing+ , Derulo.readJSON "[Infinity]" Test.~?= Nothing+ , Derulo.readJSON "[0e+-1]" Test.~?= Nothing+ , Derulo.readJSON "[-123.123foo]" Test.~?= Nothing+ , Derulo.readJSON "[-Infinity]" Test.~?= Nothing+ , Derulo.readJSON "[-foo]" Test.~?= Nothing+ , Derulo.readJSON "[- 1]" Test.~?= Nothing+ , Derulo.readJSON "[-012]" Test.~?= Nothing+ , Derulo.readJSON "[-.123]" Test.~?= Nothing+ , Derulo.readJSON "[-1x]" Test.~?= Nothing+ , Derulo.readJSON "[1ea]" Test.~?= Nothing+ , Derulo.readJSON "[1.]" Test.~?= Nothing+ , Derulo.readJSON "[.123]" Test.~?= Nothing+ , Derulo.readJSON "[1.2a-3]" Test.~?= Nothing+ , Derulo.readJSON "[1.8011670033376514H-308]" Test.~?= Nothing+ , Derulo.readJSON "[012]" Test.~?= Nothing+ , Derulo.readJSON "[\"x\", truth]" Test.~?= Nothing+ , Derulo.readJSON "{[: \"x\"}\n" Test.~?= Nothing+ , Derulo.readJSON "{\"x\", null}" Test.~?= Nothing+ , Derulo.readJSON "{\"x\"::\"b\"}" Test.~?= Nothing+ , Derulo.readJSON "{\127464\127469}" Test.~?= Nothing+ , Derulo.readJSON "{\"a\":\"a\" 123}" Test.~?= Nothing+ , Derulo.readJSON "{key: 'value'}" Test.~?= Nothing+ , Derulo.readJSON "{\"a\" b}" Test.~?= Nothing+ , Derulo.readJSON "{:\"b\"}" Test.~?= Nothing+ , Derulo.readJSON "{\"a\" \"b\"}" Test.~?= Nothing+ , Derulo.readJSON "{\"a\":" Test.~?= Nothing+ , Derulo.readJSON "{\"a\"" Test.~?= Nothing+ , Derulo.readJSON "{1:1}" Test.~?= Nothing+ , Derulo.readJSON "{9999E9999:1}" Test.~?= Nothing+ , Derulo.readJSON "{null:null,null:null}" Test.~?= Nothing+ , Derulo.readJSON "{\"id\":0,,,,,}" Test.~?= Nothing+ , Derulo.readJSON "{'a':0}" Test.~?= Nothing+ , Derulo.readJSON "{\"id\":0,}" Test.~?= Nothing+ , Derulo.readJSON "{\"a\":\"b\"}/**/" Test.~?= Nothing+ , Derulo.readJSON "{\"a\":\"b\"}/**//" Test.~?= Nothing+ , Derulo.readJSON "{\"a\":\"b\"}//" Test.~?= Nothing+ , Derulo.readJSON "{\"a\":\"b\"}/" Test.~?= Nothing+ , Derulo.readJSON "{\"a\":\"b\",,\"c\":\"d\"}" Test.~?= Nothing+ , Derulo.readJSON "{a: \"b\"}" Test.~?= Nothing+ , Derulo.readJSON "{\"a\":\"a" Test.~?= Nothing+ , Derulo.readJSON "{ \"foo\" : \"bar\", \"a\" }" Test.~?= Nothing+ , Derulo.readJSON "{\"a\":\"b\"}#" Test.~?= Nothing+ , Derulo.readJSON " " Test.~?= Nothing+ , Derulo.readJSON "[\"\\uD800\\\"]" Test.~?= Nothing+ , Derulo.readJSON "[\"\\uD800\\u\"]" Test.~?= Nothing+ , Derulo.readJSON "[\"\\uD800\\u1\"]" Test.~?= Nothing+ , Derulo.readJSON "[\"\\uD800\\u1x\"]" Test.~?= Nothing+ , Derulo.readJSON "[\233]" Test.~?= Nothing+ , Derulo.readJSON "[\"\\\NUL\"]" Test.~?= Nothing+ , Derulo.readJSON "[\"\\x00\"]" Test.~?= Nothing+ , Derulo.readJSON "[\"\\\\\\\"]" Test.~?= Nothing+ , Derulo.readJSON "[\"\\\t\"]" Test.~?= Nothing+ , Derulo.readJSON "[\"\\\127744\"]" Test.~?= Nothing+ , Derulo.readJSON "[\"\\\"]" Test.~?= Nothing+ , Derulo.readJSON "[\"\\u00A\"]" Test.~?= Nothing+ , Derulo.readJSON "[\"\\uD834\\uDd\"]" Test.~?= Nothing+ , Derulo.readJSON "[\"\\uD800\\uD800\\x\"]" Test.~?= Nothing+ , Derulo.readJSON "[\"\\a\"]" Test.~?= Nothing+ , Derulo.readJSON "[\"\\uqqqq\"]" Test.~?= Nothing+ , Derulo.readJSON "[\\u0020\"asd\"]" Test.~?= Nothing+ , Derulo.readJSON "[\\n]" Test.~?= Nothing+ , Derulo.readJSON "\"" Test.~?= Nothing+ , Derulo.readJSON "['single quote']" Test.~?= Nothing+ , Derulo.readJSON "abc" Test.~?= Nothing+ , Derulo.readJSON "[\"\\" Test.~?= Nothing+ , Derulo.readJSON "[\"a\NULa\"]" Test.~?= Nothing+ , Derulo.readJSON "[\"new\nline\"]" Test.~?= Nothing+ , Derulo.readJSON "[\"\t\"]" Test.~?= Nothing+ , Derulo.readJSON "\"\\UA66D\"" Test.~?= Nothing+ , Derulo.readJSON "\"\"x" Test.~?= Nothing+ , Derulo.readJSON "[\8288]" Test.~?= Nothing+ , Derulo.readJSON "\65279" Test.~?= Nothing+ , Derulo.readJSON "<.>" Test.~?= Nothing+ , Derulo.readJSON "[<null>]" Test.~?= Nothing+ , Derulo.readJSON "[1]x" Test.~?= Nothing+ , Derulo.readJSON "[1]]" Test.~?= Nothing+ , Derulo.readJSON "[\"asd]" Test.~?= Nothing+ , Derulo.readJSON "a\229" Test.~?= Nothing+ , Derulo.readJSON "[True]" Test.~?= Nothing+ , Derulo.readJSON "1]" Test.~?= Nothing+ , Derulo.readJSON "{\"x\": true," Test.~?= Nothing+ , Derulo.readJSON "[][]" Test.~?= Nothing+ , Derulo.readJSON "]" Test.~?= Nothing+ , Derulo.readJSON "[" Test.~?= Nothing+ , Derulo.readJSON "" Test.~?= Nothing+ , Derulo.readJSON "[\NUL]" Test.~?= Nothing+ , Derulo.readJSON "2@" Test.~?= Nothing+ , Derulo.readJSON "{}}" Test.~?= Nothing+ , Derulo.readJSON "{\"\":" Test.~?= Nothing+ , Derulo.readJSON "{\"a\":/*comment*/\"b\"}" Test.~?= Nothing+ , Derulo.readJSON "{\"a\": true} \"x\"" Test.~?= Nothing+ , Derulo.readJSON "['" Test.~?= Nothing+ , Derulo.readJSON "[," Test.~?= Nothing+ , Derulo.readJSON "[{" Test.~?= Nothing+ , Derulo.readJSON "[\"a" Test.~?= Nothing+ , Derulo.readJSON "[\"a\"" Test.~?= Nothing+ , Derulo.readJSON "{" Test.~?= Nothing+ , Derulo.readJSON "{]" Test.~?= Nothing+ , Derulo.readJSON "{," Test.~?= Nothing+ , Derulo.readJSON "{[" Test.~?= Nothing+ , Derulo.readJSON "{\"a" Test.~?= Nothing+ , Derulo.readJSON "{'a'" Test.~?= Nothing+ , Derulo.readJSON "[\"\\{[\"\\{[\"\\{[\"\\{" Test.~?= Nothing+ , Derulo.readJSON "*" Test.~?= Nothing+ , Derulo.readJSON "{\"a\":\"b\"}#{}" Test.~?= Nothing+ , Derulo.readJSON "[\\u000A\"\"]" Test.~?= Nothing+ , Derulo.readJSON "[1" Test.~?= Nothing+ , Derulo.readJSON "[ false, nul" Test.~?= Nothing+ , Derulo.readJSON "[ true, fals" Test.~?= Nothing+ , Derulo.readJSON "[ false, tru" Test.~?= Nothing+ , Derulo.readJSON "{\"asd\":\"asd\"" Test.~?= Nothing+ , Derulo.readJSON "\229" Test.~?= Nothing+ , Derulo.readJSON "[\8288]" Test.~?= Nothing+ , Derulo.readJSON "[\f]" Test.~?= Nothing+ , Derulo.readJSON "[[] ]" Test.~?= Just (Derulo.Array [Derulo.Array []])+ , Derulo.readJSON "[\"\"]" Test.~?= Just (Derulo.Array [Derulo.String ""])+ , Derulo.readJSON "[]" Test.~?= Just (Derulo.Array [])+ , Derulo.readJSON "[\"a\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "a"])+ , Derulo.readJSON "[false]"+ Test.~?= Just (Derulo.Array [Derulo.Boolean False])+ , Derulo.readJSON "[null, 1, \"1\", {}]" Test.~?= Just+ (Derulo.Array+ [Derulo.Null, Derulo.Number 1 0, Derulo.String "1", Derulo.Object []]+ )+ , Derulo.readJSON "[null]" Test.~?= Just (Derulo.Array [Derulo.Null])+ , Derulo.readJSON "[1\n]" Test.~?= Just (Derulo.Array [Derulo.Number 1 0])+ , Derulo.readJSON " [1]" Test.~?= Just (Derulo.Array [Derulo.Number 1 0])+ , Derulo.readJSON "[1,null,null,null,2]" Test.~?= Just+ (Derulo.Array+ [ Derulo.Number 1 0+ , Derulo.Null+ , Derulo.Null+ , Derulo.Null+ , Derulo.Number 2 0+ ]+ )+ , Derulo.readJSON "[2] " Test.~?= Just (Derulo.Array [Derulo.Number 2 0])+ , Derulo.readJSON "[123e65]"+ Test.~?= Just (Derulo.Array [Derulo.Number 123 65])+ , Derulo.readJSON "[0e+1]" Test.~?= Just (Derulo.Array [Derulo.Number 0 1])+ , Derulo.readJSON "[0e1]" Test.~?= Just (Derulo.Array [Derulo.Number 0 1])+ , Derulo.readJSON "[ 4]" Test.~?= Just (Derulo.Array [Derulo.Number 4 0])+ , Derulo.readJSON+ "[-0.000000000000000000000000000000000000000000000000000000000000000000000000000001]\n"+ Test.~?= Just (Derulo.Array [Derulo.Number (-1) (-78)])+ , Derulo.readJSON "[20e1]"+ Test.~?= Just (Derulo.Array [Derulo.Number 20 1])+ , Derulo.readJSON "[-0]" Test.~?= Just (Derulo.Array [Derulo.Number 0 0])+ , Derulo.readJSON "[-123]"+ Test.~?= Just (Derulo.Array [Derulo.Number (-123) 0])+ , Derulo.readJSON "[-1]"+ Test.~?= Just (Derulo.Array [Derulo.Number (-1) 0])+ , Derulo.readJSON "[-0]" Test.~?= Just (Derulo.Array [Derulo.Number 0 0])+ , Derulo.readJSON "[1E22]"+ Test.~?= Just (Derulo.Array [Derulo.Number 1 22])+ , Derulo.readJSON "[1E-2]"+ Test.~?= Just (Derulo.Array [Derulo.Number 1 (-2)])+ , Derulo.readJSON "[1E+2]" Test.~?= Just (Derulo.Array [Derulo.Number 1 2])+ , Derulo.readJSON "[123e45]"+ Test.~?= Just (Derulo.Array [Derulo.Number 123 45])+ , Derulo.readJSON "[123.456e78]"+ Test.~?= Just (Derulo.Array [Derulo.Number 123456 75])+ , Derulo.readJSON "[1e-2]"+ Test.~?= Just (Derulo.Array [Derulo.Number 1 (-2)])+ , Derulo.readJSON "[1e+2]" Test.~?= Just (Derulo.Array [Derulo.Number 1 2])+ , Derulo.readJSON "[123]"+ Test.~?= Just (Derulo.Array [Derulo.Number 123 0])+ , Derulo.readJSON "[123.456789]"+ Test.~?= Just (Derulo.Array [Derulo.Number 123456789 (-6)])+ , Derulo.readJSON "{\"asd\":\"sdf\", \"dfg\":\"fgh\"}" Test.~?= Just+ (Derulo.Object+ [("asd", Derulo.String "sdf"), ("dfg", Derulo.String "fgh")]+ )+ , Derulo.readJSON "{\"asd\":\"sdf\"}"+ Test.~?= Just (Derulo.Object [("asd", Derulo.String "sdf")])+ , Derulo.readJSON "{\"a\":\"b\",\"a\":\"c\"}" Test.~?= Just+ (Derulo.Object [("a", Derulo.String "b"), ("a", Derulo.String "c")])+ , Derulo.readJSON "{\"a\":\"b\",\"a\":\"b\"}" Test.~?= Just+ (Derulo.Object [("a", Derulo.String "b"), ("a", Derulo.String "b")])+ , Derulo.readJSON "{}" Test.~?= Just (Derulo.Object [])+ , Derulo.readJSON "{\"\":0}"+ Test.~?= Just (Derulo.Object [("", Derulo.Number 0 0)])+ , Derulo.readJSON "{\"foo\\u0000bar\": 42}"+ Test.~?= Just (Derulo.Object [("foo\NULbar", Derulo.Number 42 0)])+ , Derulo.readJSON "{ \"min\": -1.0e+28, \"max\": 1.0e+28 }" Test.~?= Just+ (Derulo.Object+ [("min", Derulo.Number (-10) 27), ("max", Derulo.Number 10 27)]+ )+ , Derulo.readJSON+ "{\"x\":[{\"id\": \"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"}], \"id\": \"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"}"+ Test.~?= Just+ (Derulo.Object+ [ ( "x"+ , Derulo.Array+ [ Derulo.Object+ [ ( "id"+ , Derulo.String+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"+ )+ ]+ ]+ )+ , ( "id"+ , Derulo.String "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"+ )+ ]+ )+ , Derulo.readJSON "{\"a\":[]}"+ Test.~?= Just (Derulo.Object [("a", Derulo.Array [])])+ , Derulo.readJSON+ "{\"title\":\"\\u041f\\u043e\\u043b\\u0442\\u043e\\u0440\\u0430 \\u0417\\u0435\\u043c\\u043b\\u0435\\u043a\\u043e\\u043f\\u0430\" }"+ Test.~?= Just+ (Derulo.Object+ [ ( "title"+ , Derulo.String+ "\1055\1086\1083\1090\1086\1088\1072 \1047\1077\1084\1083\1077\1082\1086\1087\1072"+ )+ ]+ )+ , Derulo.readJSON "{\n\"a\": \"b\"\n}"+ Test.~?= Just (Derulo.Object [("a", Derulo.String "b")])+ , Derulo.readJSON "[\"\\u0060\\u012a\\u12AB\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "`\298\4779"])+ , Derulo.readJSON "[\"\\uD801\\udc37\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\55297\56375"])+ , Derulo.readJSON "[\"\\ud83d\\ude39\\ud83d\\udc8d\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\55357\56889\55357\56461"])+ , Derulo.readJSON "[\"\\\"\\\\\\/\\b\\f\\n\\r\\t\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\"\\/\b\f\n\r\t"])+ , Derulo.readJSON "[\"\\\\u0000\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\\u0000"])+ , Derulo.readJSON "[\"\\\"\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\""])+ , Derulo.readJSON "[\"a/*b*/c/*d//e\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "a/*b*/c/*d//e"])+ , Derulo.readJSON "[\"\\\\a\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\\a"])+ , Derulo.readJSON "[\"\\\\n\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\\n"])+ , Derulo.readJSON "[\"\\u0012\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\DC2"])+ , Derulo.readJSON "[\"\\uFFFF\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\65535"])+ , Derulo.readJSON "[\"asd\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "asd"])+ , Derulo.readJSON "[ \"asd\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "asd"])+ , Derulo.readJSON "[\"\\uDBFF\\uDFFF\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\56319\57343"])+ , Derulo.readJSON "[\"new\\u00A0line\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "new\160line"])+ , Derulo.readJSON "[\"\1114111\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\1114111"])+ , Derulo.readJSON "[\"\114687\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\114687"])+ , Derulo.readJSON "[\"\65535\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\65535"])+ , Derulo.readJSON "[\"\\u0000\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\NUL"])+ , Derulo.readJSON "[\"\\u002c\"]"+ Test.~?= Just (Derulo.Array [Derulo.String ","])+ , Derulo.readJSON "[\"\960\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\960"])+ , Derulo.readJSON "[\"asd \"]"+ Test.~?= Just (Derulo.Array [Derulo.String "asd "])+ , Derulo.readJSON "\" \"" Test.~?= Just (Derulo.String " ")+ , Derulo.readJSON "[\"\\uD834\\uDd1e\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\55348\56606"])+ , Derulo.readJSON "[\"\\u0821\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\2081"])+ , Derulo.readJSON "[\"\\u0123\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\291"])+ , Derulo.readJSON "[\"\8232\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\8232"])+ , Derulo.readJSON "[\"\8233\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\8233"])+ , Derulo.readJSON "[\"\\u0061\\u30af\\u30EA\\u30b9\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "a\12463\12522\12473"])+ , Derulo.readJSON "[\"new\\u000Aline\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "new\nline"])+ , Derulo.readJSON "[\"\DEL\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\DEL"])+ , Derulo.readJSON "[\"\\uA66D\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\42605"])+ , Derulo.readJSON "[\"\\u005C\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\\"])+ , Derulo.readJSON "[\"\9026\12852\9026\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\9026\12852\9026"])+ , Derulo.readJSON "[\"\\uDBFF\\uDFFE\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\56319\57342"])+ , Derulo.readJSON "[\"\\uD83F\\uDFFE\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\55359\57342"])+ , Derulo.readJSON "[\"\\u200B\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\8203"])+ , Derulo.readJSON "[\"\\u2064\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\8292"])+ , Derulo.readJSON "[\"\\uFDD0\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\64976"])+ , Derulo.readJSON "[\"\\uFFFE\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\65534"])+ , Derulo.readJSON "[\"\\u0022\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\""])+ , Derulo.readJSON "[\"\8364\119070\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\8364\119070"])+ , Derulo.readJSON "[\"a\DELa\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "a\DELa"])+ , Derulo.readJSON "false" Test.~?= Just (Derulo.Boolean False)+ , Derulo.readJSON "42" Test.~?= Just (Derulo.Number 42 0)+ , Derulo.readJSON "-0.1" Test.~?= Just (Derulo.Number (-1) (-1))+ , Derulo.readJSON "null" Test.~?= Just Derulo.Null+ , Derulo.readJSON "\"asd\"" Test.~?= Just (Derulo.String "asd")+ , Derulo.readJSON "true" Test.~?= Just (Derulo.Boolean True)+ , Derulo.readJSON "\"\"" Test.~?= Just (Derulo.String "")+ , Derulo.readJSON "[\"a\"]\n"+ Test.~?= Just (Derulo.Array [Derulo.String "a"])+ , Derulo.readJSON "[true]"+ Test.~?= Just (Derulo.Array [Derulo.Boolean True])+ , Derulo.readJSON " [] " Test.~?= Just (Derulo.Array [])+ , Derulo.readJSON "[1.0]"+ Test.~?= Just (Derulo.Array [Derulo.Number 10 (-1)])+ , Derulo.readJSON "[1.000000000000000005]"+ Test.~?= Just (Derulo.Array [Derulo.Number 1000000000000000005 (-18)])+ , Derulo.readJSON "[1000000000000000]\n"+ Test.~?= Just (Derulo.Array [Derulo.Number 1000000000000000 0])+ , Derulo.readJSON "[10000000000000000999]"+ Test.~?= Just (Derulo.Array [Derulo.Number 10000000000000000999 0])+ , Derulo.readJSON "[1E-999]"+ Test.~?= Just (Derulo.Array [Derulo.Number 1 (-999)])+ , Derulo.readJSON "[1E6]" Test.~?= Just (Derulo.Array [Derulo.Number 1 6])+ , Derulo.readJSON "{\"\233\":\"NFC\",\"e\769\":\"NFD\"}" Test.~?= Just+ (Derulo.Object+ [("\233", Derulo.String "NFC"), ("e\769", Derulo.String "NFD")]+ )+ , Derulo.readJSON "{\"e\769\":\"NFD\",\"\233\":\"NFC\"}" Test.~?= Just+ (Derulo.Object+ [("e\769", Derulo.String "NFD"), ("\233", Derulo.String "NFC")]+ )+ , Derulo.readJSON "{\"a\":1,\"a\":2}" Test.~?= Just+ (Derulo.Object [("a", Derulo.Number 1 0), ("a", Derulo.Number 2 0)])+ , Derulo.readJSON "{\"a\":1,\"a\":1}" Test.~?= Just+ (Derulo.Object [("a", Derulo.Number 1 0), ("a", Derulo.Number 1 0)])+ , Derulo.readJSON "{\"a\":0, \"a\":-0}\n" Test.~?= Just+ (Derulo.Object [("a", Derulo.Number 0 0), ("a", Derulo.Number 0 0)])+ , Derulo.readJSON "[\"\\uD800\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\55296"])+ , Derulo.readJSON "[\"\\uD800\\uD800\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\55296\55296"])+ , Derulo.readJSON "[\"\\uD800\\uD800\\uD800\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "\55296\55296\55296"])+ , Derulo.readJSON "[\"A\\u0000B\"]"+ Test.~?= Just (Derulo.Array [Derulo.String "A\NULB"])+ ]++ let+ hasErrors = Test.errors counts /= 0+ hasFailures = Test.failures counts /= 0+ Monad.when (hasErrors || hasFailures) Exit.exitFailure
− src/exe/Main.hs
@@ -1,5 +0,0 @@-import qualified Data.Maybe as Maybe-import qualified Derulo--main :: IO ()-main = interact (Derulo.showJSON . Maybe.fromJust . Derulo.readJSON)
− src/lib/Derulo.hs
@@ -1,408 +0,0 @@-{-# LANGUAGE DeriveDataTypeable #-}-{-# LANGUAGE DeriveGeneric #-}---- | Derulo parses and renders JSON simply. It aims to provide an RFC 7159--- compliant parser and renderer without incurring any dependencies. It is--- intended to be used either for learning or in situations where dependencies--- are unwanted. In normal usage, prefer a faster, more robust library like--- [Aeson](https://hackage.haskell.org/package/aeson).------ Derulo does not export any identifiers that conflict with the prelude and--- can be imported unqualified.------ >>> import Derulo------ Use 'readJSON' to parse a 'String' into a 'JSON' value.------ >>> readJSON " null "--- Just Null------ Use 'showJSON' to render a 'JSON' value as a 'String'.------ >>> showJSON Null--- "null"-module Derulo- ( JSON(..)- , readJSON- , showJSON- ) where--import qualified Control.Monad as Monad-import qualified Data.Data as Data-import qualified Data.Functor as Functor-import qualified Data.List as List-import qualified Data.Maybe as Maybe-import qualified GHC.Generics as Generics-import qualified Text.ParserCombinators.ReadP as ReadP---- * Types--- | A JSON value as described by RFC 7159.-data JSON- = Null- | Boolean Bool- | Number Integer- Integer- | String String- | Array [JSON]- | Object [(String, JSON)]- deriving (Data.Data, Eq, Generics.Generic, Ord, Read, Show)---- * Parsing--- | Parses a string as JSON.-readJSON :: String -> Maybe JSON-readJSON string = runParser pJSON string--pJSON :: ReadP.ReadP JSON-pJSON = do- pWhitespaces- value <- pValue- ReadP.eof- pure value--pValue :: ReadP.ReadP JSON-pValue = ReadP.choice [pNull, pBoolean, pNumber, pString, pArray, pObject]--pNull :: ReadP.ReadP JSON-pNull = do- pSymbol "null"- pure Null--pBoolean :: ReadP.ReadP JSON-pBoolean = pTrue ReadP.+++ pFalse--pTrue :: ReadP.ReadP JSON-pTrue = do- pSymbol "true"- pure (Boolean True)--pFalse :: ReadP.ReadP JSON-pFalse = do- pSymbol "false"- pure (Boolean False)--pNumber :: ReadP.ReadP JSON-pNumber = do- integer <- pInteger- (fraction, precision) <- ReadP.option (0, 0) pFraction- power <- ReadP.option 0 pPower- pWhitespaces- let mantissa = integer * 10 ^ precision + negateIf (integer <= 0) fraction- let magnitude = power - precision- pure (Number mantissa magnitude)--pInteger :: ReadP.ReadP Integer-pInteger = pZero ReadP.+++ pNonZero--pZero :: ReadP.ReadP Integer-pZero = do- ReadP.optional (ReadP.char '-')- Functor.void (ReadP.char '0')- pure 0--pNonZero :: ReadP.ReadP Integer-pNonZero = do- sign <- ReadP.option '+' (ReadP.char '-')- first <- ReadP.satisfy isNonZeroDigit- rest <- ReadP.munch isDecimalDigit- case fromDecimal (first : rest) of- Nothing -> ReadP.pfail- Just nonZero -> pure (negateIf (sign == '-') nonZero)--pFraction :: ReadP.ReadP (Integer, Integer)-pFraction = do- Functor.void (ReadP.char '.')- digits <- ReadP.munch1 isDecimalDigit- case fromDecimal digits of- Nothing -> ReadP.pfail- Just fraction -> pure (fraction, List.genericLength digits)--pPower :: ReadP.ReadP Integer-pPower = do- Functor.void (ReadP.char 'E' ReadP.+++ ReadP.char 'e')- sign <- ReadP.option '+' (ReadP.char '+' ReadP.+++ ReadP.char '-')- digits <- ReadP.munch1 isDecimalDigit- case fromDecimal digits of- Nothing -> ReadP.pfail- Just magnitude -> pure (negateIf (sign == '-') magnitude)--pString :: ReadP.ReadP JSON-pString = do- string <-- ReadP.between- (ReadP.char '"')- (ReadP.char '"')- (do characters <- ReadP.many pCharacter- pure (String characters))- pWhitespaces- pure string--pCharacter :: ReadP.ReadP Char-pCharacter = pLiteral ReadP.+++ pEscape--pLiteral :: ReadP.ReadP Char-pLiteral = ReadP.satisfy isLiteral--pEscape :: ReadP.ReadP Char-pEscape = do- Functor.void (ReadP.char '\\')- escape <- ReadP.get- case escape of- '"' -> pure '"'- '/' -> pure '/'- '\\' -> pure '\\'- 'b' -> pure '\b'- 'f' -> pure '\f'- 'n' -> pure '\n'- 'r' -> pure '\r'- 't' -> pure '\t'- 'u' -> do- digits <- ReadP.count 4 (ReadP.satisfy isHexadecimalDigit)- case fromHexadecimal digits of- Nothing -> ReadP.pfail- Just point -> pure (toEnum (fromIntegral point))- _ -> ReadP.pfail--pArray :: ReadP.ReadP JSON-pArray =- ReadP.between- (pSymbol "[")- (pSymbol "]")- (do values <- ReadP.sepBy pValue (pSymbol ",")- pure (Array values))--pObject :: ReadP.ReadP JSON-pObject =- ReadP.between- (pSymbol "{")- (pSymbol "}")- (do pairs <- ReadP.sepBy pPair (pSymbol ",")- pure (Object pairs))--pPair :: ReadP.ReadP (String, JSON)-pPair = do- String key <- pString- pSymbol ":"- value <- pValue- pure (key, value)---- * Rendering--- | Renders JSON as a string.-showJSON :: JSON -> String-showJSON json = sJSON json ""--sJSON :: JSON -> ShowS-sJSON json =- case json of- Null -> sNull- Boolean boolean -> sBoolean boolean- Number mantissa magnitude -> sNumber mantissa magnitude- String string -> sString string- Array array -> sArray array- Object object -> sObject object--sNull :: ShowS-sNull = showString "null"--sBoolean :: Bool -> ShowS-sBoolean boolean =- if boolean- then sTrue- else sFalse--sTrue :: ShowS-sTrue = showString "true"--sFalse :: ShowS-sFalse = showString "false"--sNumber :: Integer -> Integer -> ShowS-sNumber mantissa magnitude = shows mantissa . showChar 'e' . shows magnitude--sString :: String -> ShowS-sString string =- sSeparatedBetween (showChar '"') (showChar '"') id sCharacter string--sCharacter :: Char -> ShowS-sCharacter character =- case character of- '"' -> showString "\\\""- '\\' -> showString "\\\\"- '\b' -> showString "\\b"- '\f' -> showString "\\f"- '\n' -> showString "\\n"- '\r' -> showString "\\r"- '\t' -> showString "\\t"- _ ->- if isControl character- then showString "\\u" .- showString- (padLeft- 4- '0'- (toHexadecimal (fromIntegral (fromEnum character))))- else showChar character--sArray :: [JSON] -> ShowS-sArray array =- sSeparatedBetween (showChar '[') (showChar ']') (showChar ',') sJSON array--sObject :: [(String, JSON)] -> ShowS-sObject object =- sSeparatedBetween (showChar '{') (showChar '}') (showChar ',') sPair object--sPair :: (String, JSON) -> ShowS-sPair (key, value) = sString key . showChar ':' . sJSON value---- * Helpers-fromBase :: Integer -> (Char -> Maybe Integer) -> String -> Maybe Integer-fromBase b f s =- Monad.foldM- (\n c -> do- d <- f c- pure (b * n + d))- 0- s--fromDecimal :: String -> Maybe Integer-fromDecimal s = fromBase 10 fromDecimalDigit s--fromDecimalDigit :: Char -> Maybe Integer-fromDecimalDigit c =- case c of- '0' -> Just 0- '1' -> Just 1- '2' -> Just 2- '3' -> Just 3- '4' -> Just 4- '5' -> Just 5- '6' -> Just 6- '7' -> Just 7- '8' -> Just 8- '9' -> Just 9- _ -> Nothing--fromHexadecimal :: String -> Maybe Integer-fromHexadecimal s = fromBase 16 fromHexadecimalDigit s--fromHexadecimalDigit :: Char -> Maybe Integer-fromHexadecimalDigit c =- case c of- 'A' -> Just 10- 'B' -> Just 11- 'C' -> Just 12- 'D' -> Just 13- 'E' -> Just 14- 'F' -> Just 15- 'a' -> Just 10- 'b' -> Just 11- 'c' -> Just 12- 'd' -> Just 13- 'e' -> Just 14- 'f' -> Just 15- _ -> fromDecimalDigit c--isControl :: Char -> Bool-isControl c = '\x00' <= c && c <= '\x1f'--isDecimalDigit :: Char -> Bool-isDecimalDigit c = '0' <= c && c <= '9'--isHexadecimalDigit :: Char -> Bool-isHexadecimalDigit c =- isDecimalDigit c || 'A' <= c && c <= 'F' || 'a' <= c && c <= 'f'--isLiteral :: Char -> Bool-isLiteral c = not (c == '"' || c == '\\' || isControl c)--isNonZeroDigit :: Char -> Bool-isNonZeroDigit c = '1' <= c && c <= '9'--isWhitespace :: Char -> Bool-isWhitespace c = c == '\t' || c == '\n' || c == '\r' || c == ' '--negateIf :: Bool -> Integer -> Integer-negateIf p n =- if p- then negate n- else n--pSymbol :: String -> ReadP.ReadP ()-pSymbol s = do- Functor.void (ReadP.string s)- pWhitespaces--pWhitespaces :: ReadP.ReadP ()-pWhitespaces = Functor.void (ReadP.munch isWhitespace)--padLeft :: Integer -> a -> [a] -> [a]-padLeft n x ys = reverse (padRight n x (reverse ys))--padRight :: Integer -> a -> [a] -> [a]-padRight n x ys =- if n <= 0- then ys- else case ys of- [] -> x : padRight (n - 1) x ys- y:zs -> y : padRight (n - 1) x zs--runParser :: ReadP.ReadP a -> String -> Maybe a-runParser p s =- Maybe.listToMaybe- (Maybe.mapMaybe- (\(x, t) ->- if null t- then Just x- else Nothing)- (ReadP.readP_to_S p s))--sBetween :: ShowS -> ShowS -> (anything -> ShowS) -> anything -> ShowS-sBetween left right render it = left . render it . right--sSeparated :: ShowS -> (element -> ShowS) -> [element] -> ShowS-sSeparated separator render elements =- case elements of- [] -> id- [element] -> render element- element:rest ->- render element . separator . sSeparated separator render rest--sSeparatedBetween ::- ShowS -> ShowS -> ShowS -> (element -> ShowS) -> [element] -> ShowS-sSeparatedBetween left right separator render elements =- sBetween left right (sSeparated separator render) elements--toBase :: Integer -> (Integer -> Maybe Char) -> Integer -> String-toBase b f n =- if n == 0- then [Maybe.fromJust (f n)]- else reverse (toBase' b f n)--toBase' :: Integer -> (Integer -> Maybe Char) -> Integer -> String-toBase' b f n =- case quotRem n b of- (0, 0) -> ""- (q, r) -> Maybe.fromJust (f r) : toBase' b f q--toHexadecimal :: Integer -> String-toHexadecimal n = toBase 16 toHexadecimalDigit n--toHexadecimalDigit :: Integer -> Maybe Char-toHexadecimalDigit n =- case n of- 0 -> Just '0'- 1 -> Just '1'- 2 -> Just '2'- 3 -> Just '3'- 4 -> Just '4'- 5 -> Just '5'- 6 -> Just '6'- 7 -> Just '7'- 8 -> Just '8'- 9 -> Just '9'- 10 -> Just 'a'- 11 -> Just 'b'- 12 -> Just 'c'- 13 -> Just 'd'- 14 -> Just 'e'- 15 -> Just 'f'- _ -> Nothing
− src/test/Main.hs
@@ -1,353 +0,0 @@-import qualified Control.Monad as Monad-import qualified Derulo-import qualified System.Exit as Exit-import qualified Test.HUnit as Test--main :: IO ()-main = do- counts <- Test.runTestTT $ Test.TestList- [ Derulo.readJSON " null " Test.~?= Just Derulo.Null- , Derulo.showJSON Derulo.Null Test.~?= "null"- , Derulo.readJSON "null" Test.~?= Just Derulo.Null- , Derulo.readJSON "true" Test.~?= Just (Derulo.Boolean True)- , Derulo.readJSON "false" Test.~?= Just (Derulo.Boolean False)- , Derulo.readJSON "0e0" Test.~?= Just (Derulo.Number 0 0)- , Derulo.readJSON "12e34" Test.~?= Just (Derulo.Number 12 34)- , Derulo.readJSON "-12e-34" Test.~?= Just (Derulo.Number (-12) (-34))- , Derulo.readJSON "\"\"" Test.~?= Just (Derulo.String "")- , Derulo.readJSON "\"js\"" Test.~?= Just (Derulo.String "js")- , Derulo.readJSON "\"\\\"\\\\\\b\\f\\n\\r\\t\"" Test.~?= Just (Derulo.String "\"\\\b\f\n\r\t")- , Derulo.readJSON "\"\\u001f\"" Test.~?= Just (Derulo.String "\x1f")- , Derulo.readJSON "[]" Test.~?= Just (Derulo.Array [])- , Derulo.readJSON "[null]" Test.~?= Just (Derulo.Array [Derulo.Null])- , Derulo.readJSON "[true,false]" Test.~?= Just (Derulo.Array [Derulo.Boolean True, Derulo.Boolean False])- , Derulo.readJSON "{}" Test.~?= Just (Derulo.Object [])- , Derulo.readJSON "{\"\":null}" Test.~?= Just (Derulo.Object [("", Derulo.Null)])- , Derulo.readJSON "{\"t\":true,\"f\":false}" Test.~?= Just (Derulo.Object [("t", Derulo.Boolean True), ("f", Derulo.Boolean False)])- , Derulo.showJSON Derulo.Null Test.~?= "null"- , Derulo.showJSON (Derulo.Boolean True) Test.~?= "true"- , Derulo.showJSON (Derulo.Boolean False) Test.~?= "false"- , Derulo.showJSON (Derulo.Number 0 0) Test.~?= "0e0"- , Derulo.showJSON (Derulo.Number 12 34) Test.~?= "12e34"- , Derulo.showJSON (Derulo.Number (-12) (-34)) Test.~?= "-12e-34"- , Derulo.showJSON (Derulo.String "") Test.~?= "\"\""- , Derulo.showJSON (Derulo.String "js") Test.~?= "\"js\""- , Derulo.showJSON (Derulo.String "\"\\\b\f\n\r\t") Test.~?= "\"\\\"\\\\\\b\\f\\n\\r\\t\""- , Derulo.showJSON (Derulo.String "\x1f") Test.~?= "\"\\u001f\""- , Derulo.showJSON (Derulo.Array []) Test.~?= "[]"- , Derulo.showJSON (Derulo.Array [Derulo.Null]) Test.~?= "[null]"- , Derulo.showJSON (Derulo.Array [Derulo.Boolean True, Derulo.Boolean False]) Test.~?= "[true,false]"- , Derulo.showJSON (Derulo.Object []) Test.~?= "{}"- , Derulo.showJSON (Derulo.Object [("", Derulo.Null)]) Test.~?= "{\"\":null}"- , Derulo.showJSON (Derulo.Object [("t", Derulo.Boolean True), ("f", Derulo.Boolean False)]) Test.~?= "{\"t\":true,\"f\":false}"- , Derulo.readJSON "[123.456e-789]" Test.~?= Just (Derulo.Array [Derulo.Number 123456 (-792)])- , Derulo.readJSON "[0.4e00669999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999969999999006]" Test.~?= Just (Derulo.Array [Derulo.Number (-4) 669999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999969999999005])- , Derulo.readJSON "[-1e+9999]" Test.~?= Just (Derulo.Array [Derulo.Number (-1) 9999])- , Derulo.readJSON "[1.5e+9999]" Test.~?= Just (Derulo.Array [Derulo.Number 15 9998])- , Derulo.readJSON "[-123123e100000]" Test.~?= Just (Derulo.Array [Derulo.Number (-123123) 100000])- , Derulo.readJSON "[123123e100000]" Test.~?= Just (Derulo.Array [Derulo.Number 123123 100000])- , Derulo.readJSON "[123e-10000000]" Test.~?= Just (Derulo.Array [Derulo.Number 123 (-10000000)])- , Derulo.readJSON "[-123123123123123123123123123123]" Test.~?= Just (Derulo.Array [Derulo.Number (-123123123123123123123123123123) 0])- , Derulo.readJSON "[100000000000000000000]" Test.~?= Just (Derulo.Array [Derulo.Number 100000000000000000000 0])- , Derulo.readJSON "[-237462374673276894279832749832423479823246327846]" Test.~?= Just (Derulo.Array [Derulo.Number (-237462374673276894279832749832423479823246327846) 0])- , Derulo.readJSON "{\"\\uDFAA\":0}" Test.~?= Just (Derulo.Object [("\57258", Derulo.Number 0 0)])- , Derulo.readJSON "[\"\\uDADA\"]" Test.~?= Just (Derulo.Array [Derulo.String "\56026"])- , Derulo.readJSON "[\"\\uD888\\u1234\"]" Test.~?= Just (Derulo.Array [Derulo.String "\55432\4660"])- , Derulo.readJSON "[\"\\uD800\\n\"]" Test.~?= Just (Derulo.Array [Derulo.String "\55296\n"])- , Derulo.readJSON "[\"\\uDd1ea\"]" Test.~?= Just (Derulo.Array [Derulo.String "\56606a"])- , Derulo.readJSON "[\"\\uD800\\uD800\\n\"]" Test.~?= Just (Derulo.Array [Derulo.String "\55296\55296\n"])- , Derulo.readJSON "[\"\\ud800\"]" Test.~?= Just (Derulo.Array [Derulo.String "\55296"])- , Derulo.readJSON "[\"\\ud800abc\"]" Test.~?= Just (Derulo.Array [Derulo.String "\55296abc"])- , Derulo.readJSON "[\"\\uDd1e\\uD834\"]" Test.~?= Just (Derulo.Array [Derulo.String "\56606\55348"])- , Derulo.readJSON "[\"\\uDFAA\"]" Test.~?= Just (Derulo.Array [Derulo.String "\57258"])- , Derulo.readJSON "\65279{}" Test.~?= Nothing- , Derulo.readJSON "[1 true]" Test.~?= Nothing- , Derulo.readJSON "[\"\": 1]" Test.~?= Nothing- , Derulo.readJSON "[\"\"]," Test.~?= Nothing- , Derulo.readJSON "[,1]" Test.~?= Nothing- , Derulo.readJSON "[1,,2]" Test.~?= Nothing- , Derulo.readJSON "[\"x\",,]" Test.~?= Nothing- , Derulo.readJSON "[\"x\"]]" Test.~?= Nothing- , Derulo.readJSON "[\"\",]" Test.~?= Nothing- , Derulo.readJSON "[\"x\"" Test.~?= Nothing- , Derulo.readJSON "[x" Test.~?= Nothing- , Derulo.readJSON "[3[4]]" Test.~?= Nothing- , Derulo.readJSON "[1:2]" Test.~?= Nothing- , Derulo.readJSON "[,]" Test.~?= Nothing- , Derulo.readJSON "[-]" Test.~?= Nothing- , Derulo.readJSON "[ , \"\"]" Test.~?= Nothing- , Derulo.readJSON "[\"a\",\n4\n,1," Test.~?= Nothing- , Derulo.readJSON "[1,]" Test.~?= Nothing- , Derulo.readJSON "[1,,]" Test.~?= Nothing- , Derulo.readJSON "[\"\va\"\\f]" Test.~?= Nothing- , Derulo.readJSON "[*]" Test.~?= Nothing- , Derulo.readJSON "[\"\"" Test.~?= Nothing- , Derulo.readJSON "[1," Test.~?= Nothing- , Derulo.readJSON "[1,\n1\n,1" Test.~?= Nothing- , Derulo.readJSON "[{}" Test.~?= Nothing- , Derulo.readJSON "[fals]" Test.~?= Nothing- , Derulo.readJSON "[nul]" Test.~?= Nothing- , Derulo.readJSON "[tru]" Test.~?= Nothing- , Derulo.readJSON "123\NUL" Test.~?= Nothing- , Derulo.readJSON "[++1234]" Test.~?= Nothing- , Derulo.readJSON "[+1]" Test.~?= Nothing- , Derulo.readJSON "[+Inf]" Test.~?= Nothing- , Derulo.readJSON "[-01]" Test.~?= Nothing- , Derulo.readJSON "[-1.0.]" Test.~?= Nothing- , Derulo.readJSON "[-2.]" Test.~?= Nothing- , Derulo.readJSON "[-NaN]" Test.~?= Nothing- , Derulo.readJSON "[.-1]" Test.~?= Nothing- , Derulo.readJSON "[.2e-3]" Test.~?= Nothing- , Derulo.readJSON "[0.1.2]" Test.~?= Nothing- , Derulo.readJSON "[0.3e+]" Test.~?= Nothing- , Derulo.readJSON "[0.3e]" Test.~?= Nothing- , Derulo.readJSON "[0.e1]" Test.~?= Nothing- , Derulo.readJSON "[0E+]" Test.~?= Nothing- , Derulo.readJSON "[0E]" Test.~?= Nothing- , Derulo.readJSON "[0e+]" Test.~?= Nothing- , Derulo.readJSON "[0e]" Test.~?= Nothing- , Derulo.readJSON "[1.0e+]" Test.~?= Nothing- , Derulo.readJSON "[1.0e-]" Test.~?= Nothing- , Derulo.readJSON "[1.0e]" Test.~?= Nothing- , Derulo.readJSON "[1 000.0]" Test.~?= Nothing- , Derulo.readJSON "[1eE2]" Test.~?= Nothing- , Derulo.readJSON "[2.e+3]" Test.~?= Nothing- , Derulo.readJSON "[2.e-3]" Test.~?= Nothing- , Derulo.readJSON "[2.e3]" Test.~?= Nothing- , Derulo.readJSON "[9.e+]" Test.~?= Nothing- , Derulo.readJSON "[Inf]" Test.~?= Nothing- , Derulo.readJSON "[NaN]" Test.~?= Nothing- , Derulo.readJSON "[\65297]" Test.~?= Nothing- , Derulo.readJSON "[1+2]" Test.~?= Nothing- , Derulo.readJSON "[0x1]" Test.~?= Nothing- , Derulo.readJSON "[0x42]" Test.~?= Nothing- , Derulo.readJSON "[Infinity]" Test.~?= Nothing- , Derulo.readJSON "[0e+-1]" Test.~?= Nothing- , Derulo.readJSON "[-123.123foo]" Test.~?= Nothing- , Derulo.readJSON "[-Infinity]" Test.~?= Nothing- , Derulo.readJSON "[-foo]" Test.~?= Nothing- , Derulo.readJSON "[- 1]" Test.~?= Nothing- , Derulo.readJSON "[-012]" Test.~?= Nothing- , Derulo.readJSON "[-.123]" Test.~?= Nothing- , Derulo.readJSON "[-1x]" Test.~?= Nothing- , Derulo.readJSON "[1ea]" Test.~?= Nothing- , Derulo.readJSON "[1.]" Test.~?= Nothing- , Derulo.readJSON "[.123]" Test.~?= Nothing- , Derulo.readJSON "[1.2a-3]" Test.~?= Nothing- , Derulo.readJSON "[1.8011670033376514H-308]" Test.~?= Nothing- , Derulo.readJSON "[012]" Test.~?= Nothing- , Derulo.readJSON "[\"x\", truth]" Test.~?= Nothing- , Derulo.readJSON "{[: \"x\"}\n" Test.~?= Nothing- , Derulo.readJSON "{\"x\", null}" Test.~?= Nothing- , Derulo.readJSON "{\"x\"::\"b\"}" Test.~?= Nothing- , Derulo.readJSON "{\127464\127469}" Test.~?= Nothing- , Derulo.readJSON "{\"a\":\"a\" 123}" Test.~?= Nothing- , Derulo.readJSON "{key: 'value'}" Test.~?= Nothing- , Derulo.readJSON "{\"a\" b}" Test.~?= Nothing- , Derulo.readJSON "{:\"b\"}" Test.~?= Nothing- , Derulo.readJSON "{\"a\" \"b\"}" Test.~?= Nothing- , Derulo.readJSON "{\"a\":" Test.~?= Nothing- , Derulo.readJSON "{\"a\"" Test.~?= Nothing- , Derulo.readJSON "{1:1}" Test.~?= Nothing- , Derulo.readJSON "{9999E9999:1}" Test.~?= Nothing- , Derulo.readJSON "{null:null,null:null}" Test.~?= Nothing- , Derulo.readJSON "{\"id\":0,,,,,}" Test.~?= Nothing- , Derulo.readJSON "{'a':0}" Test.~?= Nothing- , Derulo.readJSON "{\"id\":0,}" Test.~?= Nothing- , Derulo.readJSON "{\"a\":\"b\"}/**/" Test.~?= Nothing- , Derulo.readJSON "{\"a\":\"b\"}/**//" Test.~?= Nothing- , Derulo.readJSON "{\"a\":\"b\"}//" Test.~?= Nothing- , Derulo.readJSON "{\"a\":\"b\"}/" Test.~?= Nothing- , Derulo.readJSON "{\"a\":\"b\",,\"c\":\"d\"}" Test.~?= Nothing- , Derulo.readJSON "{a: \"b\"}" Test.~?= Nothing- , Derulo.readJSON "{\"a\":\"a" Test.~?= Nothing- , Derulo.readJSON "{ \"foo\" : \"bar\", \"a\" }" Test.~?= Nothing- , Derulo.readJSON "{\"a\":\"b\"}#" Test.~?= Nothing- , Derulo.readJSON " " Test.~?= Nothing- , Derulo.readJSON "[\"\\uD800\\\"]" Test.~?= Nothing- , Derulo.readJSON "[\"\\uD800\\u\"]" Test.~?= Nothing- , Derulo.readJSON "[\"\\uD800\\u1\"]" Test.~?= Nothing- , Derulo.readJSON "[\"\\uD800\\u1x\"]" Test.~?= Nothing- , Derulo.readJSON "[\233]" Test.~?= Nothing- , Derulo.readJSON "[\"\\\NUL\"]" Test.~?= Nothing- , Derulo.readJSON "[\"\\x00\"]" Test.~?= Nothing- , Derulo.readJSON "[\"\\\\\\\"]" Test.~?= Nothing- , Derulo.readJSON "[\"\\\t\"]" Test.~?= Nothing- , Derulo.readJSON "[\"\\\127744\"]" Test.~?= Nothing- , Derulo.readJSON "[\"\\\"]" Test.~?= Nothing- , Derulo.readJSON "[\"\\u00A\"]" Test.~?= Nothing- , Derulo.readJSON "[\"\\uD834\\uDd\"]" Test.~?= Nothing- , Derulo.readJSON "[\"\\uD800\\uD800\\x\"]" Test.~?= Nothing- , Derulo.readJSON "[\"\\a\"]" Test.~?= Nothing- , Derulo.readJSON "[\"\\uqqqq\"]" Test.~?= Nothing- , Derulo.readJSON "[\\u0020\"asd\"]" Test.~?= Nothing- , Derulo.readJSON "[\\n]" Test.~?= Nothing- , Derulo.readJSON "\"" Test.~?= Nothing- , Derulo.readJSON "['single quote']" Test.~?= Nothing- , Derulo.readJSON "abc" Test.~?= Nothing- , Derulo.readJSON "[\"\\" Test.~?= Nothing- , Derulo.readJSON "[\"a\NULa\"]" Test.~?= Nothing- , Derulo.readJSON "[\"new\nline\"]" Test.~?= Nothing- , Derulo.readJSON "[\"\t\"]" Test.~?= Nothing- , Derulo.readJSON "\"\\UA66D\"" Test.~?= Nothing- , Derulo.readJSON "\"\"x" Test.~?= Nothing- , Derulo.readJSON "[\8288]" Test.~?= Nothing- , Derulo.readJSON "\65279" Test.~?= Nothing- , Derulo.readJSON "<.>" Test.~?= Nothing- , Derulo.readJSON "[<null>]" Test.~?= Nothing- , Derulo.readJSON "[1]x" Test.~?= Nothing- , Derulo.readJSON "[1]]" Test.~?= Nothing- , Derulo.readJSON "[\"asd]" Test.~?= Nothing- , Derulo.readJSON "a\229" Test.~?= Nothing- , Derulo.readJSON "[True]" Test.~?= Nothing- , Derulo.readJSON "1]" Test.~?= Nothing- , Derulo.readJSON "{\"x\": true," Test.~?= Nothing- , Derulo.readJSON "[][]" Test.~?= Nothing- , Derulo.readJSON "]" Test.~?= Nothing- , Derulo.readJSON "[" Test.~?= Nothing- , Derulo.readJSON "" Test.~?= Nothing- , Derulo.readJSON "[\NUL]" Test.~?= Nothing- , Derulo.readJSON "2@" Test.~?= Nothing- , Derulo.readJSON "{}}" Test.~?= Nothing- , Derulo.readJSON "{\"\":" Test.~?= Nothing- , Derulo.readJSON "{\"a\":/*comment*/\"b\"}" Test.~?= Nothing- , Derulo.readJSON "{\"a\": true} \"x\"" Test.~?= Nothing- , Derulo.readJSON "['" Test.~?= Nothing- , Derulo.readJSON "[," Test.~?= Nothing- , Derulo.readJSON "[{" Test.~?= Nothing- , Derulo.readJSON "[\"a" Test.~?= Nothing- , Derulo.readJSON "[\"a\"" Test.~?= Nothing- , Derulo.readJSON "{" Test.~?= Nothing- , Derulo.readJSON "{]" Test.~?= Nothing- , Derulo.readJSON "{," Test.~?= Nothing- , Derulo.readJSON "{[" Test.~?= Nothing- , Derulo.readJSON "{\"a" Test.~?= Nothing- , Derulo.readJSON "{'a'" Test.~?= Nothing- , Derulo.readJSON "[\"\\{[\"\\{[\"\\{[\"\\{" Test.~?= Nothing- , Derulo.readJSON "*" Test.~?= Nothing- , Derulo.readJSON "{\"a\":\"b\"}#{}" Test.~?= Nothing- , Derulo.readJSON "[\\u000A\"\"]" Test.~?= Nothing- , Derulo.readJSON "[1" Test.~?= Nothing- , Derulo.readJSON "[ false, nul" Test.~?= Nothing- , Derulo.readJSON "[ true, fals" Test.~?= Nothing- , Derulo.readJSON "[ false, tru" Test.~?= Nothing- , Derulo.readJSON "{\"asd\":\"asd\"" Test.~?= Nothing- , Derulo.readJSON "\229" Test.~?= Nothing- , Derulo.readJSON "[\8288]" Test.~?= Nothing- , Derulo.readJSON "[\f]" Test.~?= Nothing- , Derulo.readJSON "[[] ]" Test.~?= Just (Derulo.Array [Derulo.Array []])- , Derulo.readJSON "[\"\"]" Test.~?= Just (Derulo.Array [Derulo.String ""])- , Derulo.readJSON "[]" Test.~?= Just (Derulo.Array [])- , Derulo.readJSON "[\"a\"]" Test.~?= Just (Derulo.Array [Derulo.String "a"])- , Derulo.readJSON "[false]" Test.~?= Just (Derulo.Array [Derulo.Boolean False])- , Derulo.readJSON "[null, 1, \"1\", {}]" Test.~?= Just (Derulo.Array [Derulo.Null, Derulo.Number 1 0, Derulo.String "1", Derulo.Object []])- , Derulo.readJSON "[null]" Test.~?= Just (Derulo.Array [Derulo.Null])- , Derulo.readJSON "[1\n]" Test.~?= Just (Derulo.Array [Derulo.Number 1 0])- , Derulo.readJSON " [1]" Test.~?= Just (Derulo.Array [Derulo.Number 1 0])- , Derulo.readJSON "[1,null,null,null,2]" Test.~?= Just (Derulo.Array [Derulo.Number 1 0, Derulo.Null, Derulo.Null, Derulo.Null, Derulo.Number 2 0])- , Derulo.readJSON "[2] " Test.~?= Just (Derulo.Array [Derulo.Number 2 0])- , Derulo.readJSON "[123e65]" Test.~?= Just (Derulo.Array [Derulo.Number 123 65])- , Derulo.readJSON "[0e+1]" Test.~?= Just (Derulo.Array [Derulo.Number 0 1])- , Derulo.readJSON "[0e1]" Test.~?= Just (Derulo.Array [Derulo.Number 0 1])- , Derulo.readJSON "[ 4]" Test.~?= Just (Derulo.Array [Derulo.Number 4 0])- , Derulo.readJSON "[-0.000000000000000000000000000000000000000000000000000000000000000000000000000001]\n" Test.~?= Just (Derulo.Array [Derulo.Number (-1) (-78)])- , Derulo.readJSON "[20e1]" Test.~?= Just (Derulo.Array [Derulo.Number 20 1])- , Derulo.readJSON "[-0]" Test.~?= Just (Derulo.Array [Derulo.Number 0 0])- , Derulo.readJSON "[-123]" Test.~?= Just (Derulo.Array [Derulo.Number (-123) 0])- , Derulo.readJSON "[-1]" Test.~?= Just (Derulo.Array [Derulo.Number (-1) 0])- , Derulo.readJSON "[-0]" Test.~?= Just (Derulo.Array [Derulo.Number 0 0])- , Derulo.readJSON "[1E22]" Test.~?= Just (Derulo.Array [Derulo.Number 1 22])- , Derulo.readJSON "[1E-2]" Test.~?= Just (Derulo.Array [Derulo.Number 1 (-2)])- , Derulo.readJSON "[1E+2]" Test.~?= Just (Derulo.Array [Derulo.Number 1 2])- , Derulo.readJSON "[123e45]" Test.~?= Just (Derulo.Array [Derulo.Number 123 45])- , Derulo.readJSON "[123.456e78]" Test.~?= Just (Derulo.Array [Derulo.Number 123456 75])- , Derulo.readJSON "[1e-2]" Test.~?= Just (Derulo.Array [Derulo.Number 1 (-2)])- , Derulo.readJSON "[1e+2]" Test.~?= Just (Derulo.Array [Derulo.Number 1 2])- , Derulo.readJSON "[123]" Test.~?= Just (Derulo.Array [Derulo.Number 123 0])- , Derulo.readJSON "[123.456789]" Test.~?= Just (Derulo.Array [Derulo.Number 123456789 (-6)])- , Derulo.readJSON "{\"asd\":\"sdf\", \"dfg\":\"fgh\"}" Test.~?= Just (Derulo.Object [("asd", Derulo.String "sdf"), ("dfg", Derulo.String "fgh")])- , Derulo.readJSON "{\"asd\":\"sdf\"}" Test.~?= Just (Derulo.Object [("asd", Derulo.String "sdf")])- , Derulo.readJSON "{\"a\":\"b\",\"a\":\"c\"}" Test.~?= Just (Derulo.Object [("a", Derulo.String "b"), ("a", Derulo.String "c")])- , Derulo.readJSON "{\"a\":\"b\",\"a\":\"b\"}" Test.~?= Just (Derulo.Object [("a", Derulo.String "b"), ("a", Derulo.String "b")])- , Derulo.readJSON "{}" Test.~?= Just (Derulo.Object [])- , Derulo.readJSON "{\"\":0}" Test.~?= Just (Derulo.Object [("", Derulo.Number 0 0)])- , Derulo.readJSON "{\"foo\\u0000bar\": 42}" Test.~?= Just (Derulo.Object [("foo\NULbar", Derulo.Number 42 0)])- , Derulo.readJSON "{ \"min\": -1.0e+28, \"max\": 1.0e+28 }" Test.~?= Just (Derulo.Object [("min", Derulo.Number (-10) 27), ("max", Derulo.Number 10 27)])- , Derulo.readJSON "{\"x\":[{\"id\": \"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"}], \"id\": \"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"}" Test.~?= Just (Derulo.Object [("x", Derulo.Array [Derulo.Object [("id", Derulo.String "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")]]), ("id", Derulo.String "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")])- , Derulo.readJSON "{\"a\":[]}" Test.~?= Just (Derulo.Object [("a", Derulo.Array [])])- , Derulo.readJSON "{\"title\":\"\\u041f\\u043e\\u043b\\u0442\\u043e\\u0440\\u0430 \\u0417\\u0435\\u043c\\u043b\\u0435\\u043a\\u043e\\u043f\\u0430\" }" Test.~?= Just (Derulo.Object [("title", Derulo.String "\1055\1086\1083\1090\1086\1088\1072 \1047\1077\1084\1083\1077\1082\1086\1087\1072")])- , Derulo.readJSON "{\n\"a\": \"b\"\n}" Test.~?= Just (Derulo.Object [("a", Derulo.String "b")])- , Derulo.readJSON "[\"\\u0060\\u012a\\u12AB\"]" Test.~?= Just (Derulo.Array [Derulo.String "`\298\4779"])- , Derulo.readJSON "[\"\\uD801\\udc37\"]" Test.~?= Just (Derulo.Array [Derulo.String "\55297\56375"])- , Derulo.readJSON "[\"\\ud83d\\ude39\\ud83d\\udc8d\"]" Test.~?= Just (Derulo.Array [Derulo.String "\55357\56889\55357\56461"])- , Derulo.readJSON "[\"\\\"\\\\\\/\\b\\f\\n\\r\\t\"]" Test.~?= Just (Derulo.Array [Derulo.String "\"\\/\b\f\n\r\t"])- , Derulo.readJSON "[\"\\\\u0000\"]" Test.~?= Just (Derulo.Array [Derulo.String "\\u0000"])- , Derulo.readJSON "[\"\\\"\"]" Test.~?= Just (Derulo.Array [Derulo.String "\""])- , Derulo.readJSON "[\"a/*b*/c/*d//e\"]" Test.~?= Just (Derulo.Array [Derulo.String "a/*b*/c/*d//e"])- , Derulo.readJSON "[\"\\\\a\"]" Test.~?= Just (Derulo.Array [Derulo.String "\\a"])- , Derulo.readJSON "[\"\\\\n\"]" Test.~?= Just (Derulo.Array [Derulo.String "\\n"])- , Derulo.readJSON "[\"\\u0012\"]" Test.~?= Just (Derulo.Array [Derulo.String "\DC2"])- , Derulo.readJSON "[\"\\uFFFF\"]" Test.~?= Just (Derulo.Array [Derulo.String "\65535"])- , Derulo.readJSON "[\"asd\"]" Test.~?= Just (Derulo.Array [Derulo.String "asd"])- , Derulo.readJSON "[ \"asd\"]" Test.~?= Just (Derulo.Array [Derulo.String "asd"])- , Derulo.readJSON "[\"\\uDBFF\\uDFFF\"]" Test.~?= Just (Derulo.Array [Derulo.String "\56319\57343"])- , Derulo.readJSON "[\"new\\u00A0line\"]" Test.~?= Just (Derulo.Array [Derulo.String "new\160line"])- , Derulo.readJSON "[\"\1114111\"]" Test.~?= Just (Derulo.Array [Derulo.String "\1114111"])- , Derulo.readJSON "[\"\114687\"]" Test.~?= Just (Derulo.Array [Derulo.String "\114687"])- , Derulo.readJSON "[\"\65535\"]" Test.~?= Just (Derulo.Array [Derulo.String "\65535"])- , Derulo.readJSON "[\"\\u0000\"]" Test.~?= Just (Derulo.Array [Derulo.String "\NUL"])- , Derulo.readJSON "[\"\\u002c\"]" Test.~?= Just (Derulo.Array [Derulo.String ","])- , Derulo.readJSON "[\"\960\"]" Test.~?= Just (Derulo.Array [Derulo.String "\960"])- , Derulo.readJSON "[\"asd \"]" Test.~?= Just (Derulo.Array [Derulo.String "asd "])- , Derulo.readJSON "\" \"" Test.~?= Just (Derulo.String " ")- , Derulo.readJSON "[\"\\uD834\\uDd1e\"]" Test.~?= Just (Derulo.Array [Derulo.String "\55348\56606"])- , Derulo.readJSON "[\"\\u0821\"]" Test.~?= Just (Derulo.Array [Derulo.String "\2081"])- , Derulo.readJSON "[\"\\u0123\"]" Test.~?= Just (Derulo.Array [Derulo.String "\291"])- , Derulo.readJSON "[\"\8232\"]" Test.~?= Just (Derulo.Array [Derulo.String "\8232"])- , Derulo.readJSON "[\"\8233\"]" Test.~?= Just (Derulo.Array [Derulo.String "\8233"])- , Derulo.readJSON "[\"\\u0061\\u30af\\u30EA\\u30b9\"]" Test.~?= Just (Derulo.Array [Derulo.String "a\12463\12522\12473"])- , Derulo.readJSON "[\"new\\u000Aline\"]" Test.~?= Just (Derulo.Array [Derulo.String "new\nline"])- , Derulo.readJSON "[\"\DEL\"]" Test.~?= Just (Derulo.Array [Derulo.String "\DEL"])- , Derulo.readJSON "[\"\\uA66D\"]" Test.~?= Just (Derulo.Array [Derulo.String "\42605"])- , Derulo.readJSON "[\"\\u005C\"]" Test.~?= Just (Derulo.Array [Derulo.String "\\"])- , Derulo.readJSON "[\"\9026\12852\9026\"]" Test.~?= Just (Derulo.Array [Derulo.String "\9026\12852\9026"])- , Derulo.readJSON "[\"\\uDBFF\\uDFFE\"]" Test.~?= Just (Derulo.Array [Derulo.String "\56319\57342"])- , Derulo.readJSON "[\"\\uD83F\\uDFFE\"]" Test.~?= Just (Derulo.Array [Derulo.String "\55359\57342"])- , Derulo.readJSON "[\"\\u200B\"]" Test.~?= Just (Derulo.Array [Derulo.String "\8203"])- , Derulo.readJSON "[\"\\u2064\"]" Test.~?= Just (Derulo.Array [Derulo.String "\8292"])- , Derulo.readJSON "[\"\\uFDD0\"]" Test.~?= Just (Derulo.Array [Derulo.String "\64976"])- , Derulo.readJSON "[\"\\uFFFE\"]" Test.~?= Just (Derulo.Array [Derulo.String "\65534"])- , Derulo.readJSON "[\"\\u0022\"]" Test.~?= Just (Derulo.Array [Derulo.String "\""])- , Derulo.readJSON "[\"\8364\119070\"]" Test.~?= Just (Derulo.Array [Derulo.String "\8364\119070"])- , Derulo.readJSON "[\"a\DELa\"]" Test.~?= Just (Derulo.Array [Derulo.String "a\DELa"])- , Derulo.readJSON "false" Test.~?= Just (Derulo.Boolean False)- , Derulo.readJSON "42" Test.~?= Just (Derulo.Number 42 0)- , Derulo.readJSON "-0.1" Test.~?= Just (Derulo.Number (-1) (-1))- , Derulo.readJSON "null" Test.~?= Just Derulo.Null- , Derulo.readJSON "\"asd\"" Test.~?= Just (Derulo.String "asd")- , Derulo.readJSON "true" Test.~?= Just (Derulo.Boolean True)- , Derulo.readJSON "\"\"" Test.~?= Just (Derulo.String "")- , Derulo.readJSON "[\"a\"]\n" Test.~?= Just (Derulo.Array [Derulo.String "a"])- , Derulo.readJSON "[true]" Test.~?= Just (Derulo.Array [Derulo.Boolean True])- , Derulo.readJSON " [] " Test.~?= Just (Derulo.Array [])- , Derulo.readJSON "[1.0]" Test.~?= Just (Derulo.Array [Derulo.Number 10 (-1)])- , Derulo.readJSON "[1.000000000000000005]" Test.~?= Just (Derulo.Array [Derulo.Number 1000000000000000005 (-18)])- , Derulo.readJSON "[1000000000000000]\n" Test.~?= Just (Derulo.Array [Derulo.Number 1000000000000000 0])- , Derulo.readJSON "[10000000000000000999]" Test.~?= Just (Derulo.Array [Derulo.Number 10000000000000000999 0])- , Derulo.readJSON "[1E-999]" Test.~?= Just (Derulo.Array [Derulo.Number 1 (-999)])- , Derulo.readJSON "[1E6]" Test.~?= Just (Derulo.Array [Derulo.Number 1 6])- , Derulo.readJSON "{\"\233\":\"NFC\",\"e\769\":\"NFD\"}" Test.~?= Just (Derulo.Object [("\233", Derulo.String "NFC"), ("e\769", Derulo.String "NFD")])- , Derulo.readJSON "{\"e\769\":\"NFD\",\"\233\":\"NFC\"}" Test.~?= Just (Derulo.Object [("e\769", Derulo.String "NFD"), ("\233", Derulo.String "NFC")])- , Derulo.readJSON "{\"a\":1,\"a\":2}" Test.~?= Just (Derulo.Object [("a", Derulo.Number 1 0), ("a", Derulo.Number 2 0)])- , Derulo.readJSON "{\"a\":1,\"a\":1}" Test.~?= Just (Derulo.Object [("a", Derulo.Number 1 0), ("a", Derulo.Number 1 0)])- , Derulo.readJSON "{\"a\":0, \"a\":-0}\n" Test.~?= Just (Derulo.Object [("a", Derulo.Number 0 0), ("a", Derulo.Number 0 0)])- , Derulo.readJSON "[\"\\uD800\"]" Test.~?= Just (Derulo.Array [Derulo.String "\55296"])- , Derulo.readJSON "[\"\\uD800\\uD800\"]" Test.~?= Just (Derulo.Array [Derulo.String "\55296\55296"])- , Derulo.readJSON "[\"\\uD800\\uD800\\uD800\"]" Test.~?= Just (Derulo.Array [Derulo.String "\55296\55296\55296"])- , Derulo.readJSON "[\"A\\u0000B\"]" Test.~?= Just (Derulo.Array [Derulo.String "A\NULB"])- ]-- let- hasErrors = Test.errors counts /= 0- hasFailures = Test.failures counts /= 0- Monad.when (hasErrors || hasFailures) Exit.exitFailure