http://hackage.haskell.org/package/aeson-0.8.0.1 decode = decodeWith jsonEOF fromJSON decode :: (FromJSON a) => L.ByteString -> Maybe a decode = decodeWith jsonEOF fromJSON http://hackage.haskell.org/package/aeson-0.8.0.1/docs/src/Data-Aeson.html#decode import Data.Aeson.Parser.Internal (decodeWith, decodeStrictWith, eitherDecodeWith, eitherDecodeStrictWith, jsonEOF, json, jsonEOF', json') import qualified Data.Attoparsec.Lazy as L http://hackage.haskell.org/package/aeson-0.6.0.0/docs/src/Data-Aeson-Parser-Internal.html decodeWith :: Parser Value -> (Value -> Result a) -> L.ByteString -> Maybe a decodeWith p to s = case L.parse p s of L.Done _ v -> case to v of Success a -> Just a _ -> Nothing import qualified Data.Attoparsec.Lazy as L https://hackage.haskell.org/package/attoparsec-0.12.1.2 import Data.Attoparsec.ByteString.Lazy https://hackage.haskell.org/package/attoparsec-0.12.1.2/docs/Data-Attoparsec-ByteString-Lazy.html jsonEOF :: Parser Value jsonEOF = json <* skipSpace <* endOfInput sepBy1 :: Alternative f => f a -> f s -> f [a] sepBy1 p s = scan where scan = liftA2 (:) p ((s *> scan) <|> pure []) scan :: s -> (s -> Char -> Maybe s) -> Parser Text A stateful scanner. The predicate consumes and transforms a state argument, and each transformed state is passed to successive invocations of the predicate on each character of the input until one returns Nothing or the input ends. This parser does not fail. It will return an empty string if the predicate returns Nothing on the first character of input. Note: Because this parser does not fail, do not use it with combinators such as many, because such parsers loop until a failure occurs. Careless use will thus result in an infinite loop. Control.Applicative liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c http://hackage.haskell.org/package/attoparsec-0.12.1.2/docs/Data-Attoparsec-Text.html#v:Partial Incremental input attoparsec supports incremental input, meaning that you can feed it a Text that represents only part of the expected total amount of data to parse. If your parser reaches the end of a fragment of input and could consume more input, it will suspend parsing and return a Partial continuation. Supplying the Partial continuation with another string will resume parsing at the point where it was suspended, with the string you supplied used as new input at the end of the existing input. You must be prepared for the result of the resumed parse to be another Partial continuation. To indicate that you have no more input, supply the Partial continuation with an empty Text. Remember that some parsing combinators will not return a result until they reach the end of input. They may thus cause Partial results to be returned. If you do not need support for incremental input, consider using the parseOnly function to run your parser. It will never prompt for more input. Note: incremental input does not imply that attoparsec will release portions of its internal state for garbage collection as it proceeds. Its internal representation is equivalent to a single Text: if you feed incremental input to an a parser, it will require memory proportional to the amount of input you supply. (This is necessary to support arbitrary backtracking.)