-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Better error messages when decoding JSON values.
--   
--   A small package which gives you the tools to build parsers to decode
--   JSON values, and gives good error messages when parsing fails. See
--   also <a>http://harry.garrood.me/blog/aeson-better-errors/</a>.
@package aeson-better-errors
@version 0.9.0.1

module Data.Aeson.BetterErrors.Internal

-- | The type of parsers: things which consume JSON values and produce
--   either detailed errors or successfully parsed values (of other types).
--   
--   The <tt>err</tt> type parameter is for custom validation errors; for
--   parsers that don't produce any custom validation errors, I recommend
--   you just stick a type variable in for full generality:
--   
--   <pre>
--   asTuple :: Parse e (Int, Int)
--   asTuple = (,) &lt;$&gt; nth 0 asIntegral &lt;*&gt; nth 1 asIntegral
--   </pre>
--   
--   The <tt>m</tt> parameter allows you to run the parser within an
--   abitrary underlying Monad. You may want to use <a>Parse</a> in most
--   cases instead, and all functions in this module work on either.
newtype ParseT err m a
ParseT :: (ReaderT ParseReader (ExceptT (ParseError err) m) a) -> ParseT err m a

-- | This is the standard version of <a>ParseT</a> over the <a>Identity</a>
--   Monad, for running pure parsers.
type Parse err a = ParseT err Identity a
runParseT :: ParseT err m a -> Value -> m (Either (ParseError err) a)
runParse :: Parse err a -> Value -> Either (ParseError err) a
mapParseT :: (ReaderT ParseReader (ExceptT (ParseError err) m) a -> ReaderT ParseReader (ExceptT (ParseError err') m') a') -> ParseT err m a -> ParseT err' m' a'

-- | Transform the error of a parser according to the given function.
mapError :: Functor m => (err -> err') -> ParseT err m a -> ParseT err' m a

-- | An infix version of <a>mapError</a>.
(.!) :: Functor m => ParseT err m a -> (err -> err') -> ParseT err' m a

-- | The type of parsers which never produce custom validation errors.
type Parse' a = Parse Void a
runParserT :: Monad m => (s -> Either String Value) -> ParseT err m a -> s -> m (Either (ParseError err) a)
runParser :: (s -> Either String Value) -> Parse err a -> s -> Either (ParseError err) a

-- | Like <a>parse</a> but runs the parser on an arbitrary underlying
--   Monad.
parseM :: Monad m => ParseT err m a -> ByteString -> m (Either (ParseError err) a)

-- | Run a parser with a lazy <a>ByteString</a> containing JSON data. Note
--   that the normal caveat applies: the JSON supplied must contain either
--   an object or an array for this to work.
parse :: Parse err a -> ByteString -> Either (ParseError err) a

-- | Like <a>parseStrict</a> but runs the parser on an arbitrary underlying
--   Monad.
parseStrictM :: Monad m => ParseT err m a -> ByteString -> m (Either (ParseError err) a)

-- | Run a parser with a strict <a>ByteString</a> containing JSON data.
--   Note that the normal caveat applies: the JSON supplied must contain
--   either an object or an array for this to work.
parseStrict :: Parse err a -> ByteString -> Either (ParseError err) a

-- | Like <a>parseValue</a> but runs the parser on an arbitrary underlying
--   Monad.
parseValueM :: Monad m => ParseT err m a -> Value -> m (Either (ParseError err) a)

-- | Run a parser with a pre-parsed JSON <a>Value</a>.
parseValue :: Parse err a -> Value -> Either (ParseError err) a

-- | This function is useful when you have a <tt><a>Parse</a> err a</tt>
--   and you want to obtain an instance for <tt><a>FromJSON</a> a</tt>.
--   Simply define:
--   
--   <pre>
--   parseJSON = toAesonParser showMyCustomError myParser
--   </pre>
toAesonParser :: (err -> Text) -> Parse err a -> Value -> Parser a

-- | Take a parser which never produces custom validation errors and turn
--   it into an Aeson parser. Note that in this case, there is no need to
--   provide a display function.
toAesonParser' :: Parse' a -> Value -> Parser a

-- | Create a parser for any type, using its FromJSON instance. Generally,
--   you should prefer to write parsers using the other functions in this
--   module; <a>key</a>, <a>asString</a>, etc, since they will usually
--   generate better error messages. However this function is also useful
--   occasionally.
fromAesonParser :: (Functor m, Monad m) => FromJSON a => ParseT e m a

-- | Data used internally by the <a>Parse</a> type.
data ParseReader
ParseReader :: DList PathPiece -> Value -> ParseReader
[rdrPath] :: ParseReader -> DList PathPiece
[rdrValue] :: ParseReader -> Value
appendPath :: PathPiece -> ParseReader -> ParseReader
setValue :: Value -> ParseReader -> ParseReader

-- | A piece of a path leading to a specific part of the JSON data.
--   Internally, a list of these is maintained as the parser traverses the
--   JSON data. This list is included in the error if one occurs.
data PathPiece
ObjectKey :: Text -> PathPiece
ArrayIndex :: Int -> PathPiece

-- | A value indicating that the JSON could not be decoded successfully.
data ParseError err

-- | Indicates a syntax error in the JSON string. Unfortunately, in this
--   case, Aeson's errors are not very helpful.
InvalidJSON :: String -> ParseError err

-- | Indicates a decoding error; the input was parsed as JSON successfully,
--   but a value of the required type could not be constructed, perhaps
--   because of a missing key or type mismatch.
BadSchema :: [PathPiece] -> (ErrorSpecifics err) -> ParseError err

-- | The type of parse errors which never involve custom validation errors.
type ParseError' = ParseError Void

-- | Detailed information in the case where a value could be parsed as
--   JSON, but a value of the required type could not be constructed from
--   it, for some reason.
data ErrorSpecifics err
KeyMissing :: Text -> ErrorSpecifics err
OutOfBounds :: Int -> ErrorSpecifics err

-- | Expected type, actual value
WrongType :: JSONType -> Value -> ErrorSpecifics err
ExpectedIntegral :: Double -> ErrorSpecifics err

-- | An error arising inside a <a>FromJSON</a> instance.
FromAeson :: String -> ErrorSpecifics err
CustomError :: err -> ErrorSpecifics err

-- | The type of error specifics which never involve custom validation
--   errors.
type ErrorSpecifics' = ErrorSpecifics Void

-- | An enumeration of the different types that JSON values may take.
data JSONType
TyObject :: JSONType
TyArray :: JSONType
TyString :: JSONType
TyNumber :: JSONType
TyBool :: JSONType
TyNull :: JSONType
displayJSONType :: JSONType -> Text

-- | Turn a <a>ParseError</a> into a human-readable list of <a>Text</a>
--   values. They will be in a sensible order. For example, you can feed
--   the result to <tt>mapM putStrLn</tt>, or <tt>unlines</tt>.
displayError :: (err -> Text) -> ParseError err -> [Text]

-- | A version of <a>displayError</a> for parsers which do not produce
--   custom validation errors.
displayError' :: ParseError' -> [Text]
displayPath :: [PathPiece] -> Text
displaySpecifics :: (err -> Text) -> ErrorSpecifics err -> [Text]

-- | A version of <a>displaySpecifics</a> for parsers which do not produce
--   custom validation errors.
displaySpecifics' :: ErrorSpecifics' -> [Text]

-- | Get the type of a JSON value.
jsonTypeOf :: Value -> JSONType
liftParseT :: (Functor m, Monad m) => (Value -> ExceptT (ErrorSpecifics err) m a) -> ParseT err m a
liftParseM :: (Functor m, Monad m) => (Value -> m (Either (ErrorSpecifics err) a)) -> ParseT err m a

-- | Lift any parsing function into the <a>Parse</a> type.
liftParse :: (Functor m, Monad m) => (Value -> Either (ErrorSpecifics err) a) -> ParseT err m a

-- | Aborts parsing, due to an error in the structure of the JSON - that
--   is, any error other than the JSON not actually being parseable into a
--   <a>Value</a>.
badSchema :: (Functor m, Monad m) => ErrorSpecifics err -> ParseT err m a
as :: (Functor m, Monad m) => (Value -> Maybe a) -> JSONType -> ParseT err m a

-- | Return the current JSON <a>Value</a> as is. This does no error
--   checking and thus always succeeds. You probably don't want this parser
--   unless the JSON at the current part of your structure is truly
--   arbitrary. You should prefer to use more specific parsers, like
--   <a>asText</a> or <a>asIntegral</a>, where possible.
asValue :: (Functor m, Monad m) => ParseT err m Value

-- | Parse a single JSON string as <a>Text</a>.
asText :: (Functor m, Monad m) => ParseT err m Text

-- | Parse a single JSON string as a <a>String</a>.
asString :: (Functor m, Monad m) => ParseT err m String

-- | Parse a single JSON number as a <a>Scientific</a>.
asScientific :: (Functor m, Monad m) => ParseT err m Scientific

-- | Parse a single JSON number as any <a>Integral</a> type.
asIntegral :: (Functor m, Monad m, Integral a) => ParseT err m a

-- | Parse a single JSON number as any <a>RealFloat</a> type.
asRealFloat :: (Functor m, Monad m, RealFloat a) => ParseT err m a

-- | Parse a single JSON boolean as a <a>Bool</a>.
asBool :: (Functor m, Monad m) => ParseT err m Bool

-- | Parse a JSON object, as an <a>Object</a>. You should prefer functions
--   like <a>eachInObject</a> where possible, since they will usually
--   generate better error messages.
asObject :: (Functor m, Monad m) => ParseT err m Object

-- | Parse a JSON array, as an <a>Array</a>. You should prefer functions
--   like <a>eachInArray</a> where possible, since they will usually
--   generate better error messages.
asArray :: (Functor m, Monad m) => ParseT err m Array

-- | Parse a single JSON null value. Useful if you want to throw an error
--   in the case where something is not null.
asNull :: (Functor m, Monad m) => ParseT err m ()

-- | Given a parser, transform it into a parser which returns
--   <tt>Nothing</tt> when supplied with a JSON <tt>null</tt>, and
--   otherwise, attempts to parse with the original parser; if this
--   succeeds, the result becomes a <tt>Just</tt> value.
perhaps :: (Functor m, Monad m) => ParseT err m a -> ParseT err m (Maybe a)

-- | Take the value corresponding to a given key in the current object.
key :: (Functor m, Monad m) => Text -> ParseT err m a -> ParseT err m a

-- | Take the value corresponding to a given key in the current object, or
--   if no property exists with that key, use the supplied default.
keyOrDefault :: (Functor m, Monad m) => Text -> a -> ParseT err m a -> ParseT err m a

-- | Take the value corresponding to a given key in the current object, or
--   if no property exists with that key, return Nothing .
keyMay :: (Functor m, Monad m) => Text -> ParseT err m a -> ParseT err m (Maybe a)
key' :: (Functor m, Monad m) => ParseT err m a -> Text -> ParseT err m a -> ParseT err m a

-- | Take the nth value of the current array.
nth :: (Functor m, Monad m) => Int -> ParseT err m a -> ParseT err m a

-- | Take the nth value of the current array, or if no value exists with
--   that index, use the supplied default.
nthOrDefault :: (Functor m, Monad m) => Int -> a -> ParseT err m a -> ParseT err m a

-- | Take the nth value of the current array, or if no value exists with
--   that index, return Nothing.
nthMay :: (Functor m, Monad m) => Int -> ParseT err m a -> ParseT err m (Maybe a)
nth' :: (Functor m, Monad m) => ParseT err m a -> Int -> ParseT err m a -> ParseT err m a

-- | Attempt to parse each value in the array with the given parser, and
--   collect the results.
eachInArray :: (Functor m, Monad m) => ParseT err m a -> ParseT err m [a]

-- | Parse each property in an object with the given parser, given the key
--   as an argument, and collect the results.
forEachInObject :: (Functor m, Monad m) => (Text -> ParseT err m a) -> ParseT err m [a]

-- | Attempt to parse each property value in the object with the given
--   parser, and collect the results.
eachInObject :: (Functor m, Monad m) => ParseT err m a -> ParseT err m [(Text, a)]

-- | Attempt to parse each property in the object: parse the key with the
--   given validation function, parse the value with the given parser, and
--   collect the results.
eachInObjectWithKey :: (Functor m, Monad m) => (Text -> Either err k) -> ParseT err m a -> ParseT err m [(k, a)]

-- | Lifts a function attempting to validate an arbitrary JSON value into a
--   parser. You should only use this if absolutely necessary; the other
--   functions in this module will generally give better error reporting.
withValue :: (Functor m, Monad m) => (Value -> Either err a) -> ParseT err m a
withValueM :: (Functor m, Monad m) => (Value -> m (Either err a)) -> ParseT err m a
liftEither :: (Functor m, Monad m) => Either err a -> ParseT err m a
withM :: (Functor m, Monad m) => ParseT err m a -> (a -> m (Either err b)) -> ParseT err m b
with :: (Functor m, Monad m) => ParseT err m a -> (a -> Either err b) -> ParseT err m b
withTextM :: (Functor m, Monad m) => (Text -> m (Either err a)) -> ParseT err m a
withText :: (Functor m, Monad m) => (Text -> Either err a) -> ParseT err m a
withStringM :: (Functor m, Monad m) => (String -> m (Either err a)) -> ParseT err m a
withString :: (Functor m, Monad m) => (String -> Either err a) -> ParseT err m a
withScientificM :: (Functor m, Monad m) => (Scientific -> m (Either err a)) -> ParseT err m a
withScientific :: (Functor m, Monad m) => (Scientific -> Either err a) -> ParseT err m a
withIntegralM :: (Functor m, Monad m, Integral a) => (a -> m (Either err b)) -> ParseT err m b
withIntegral :: (Functor m, Monad m, Integral a) => (a -> Either err b) -> ParseT err m b
withRealFloatM :: (Functor m, Monad m, RealFloat a) => (a -> m (Either err b)) -> ParseT err m b
withRealFloat :: (Functor m, Monad m, RealFloat a) => (a -> Either err b) -> ParseT err m b
withBoolM :: (Functor m, Monad m) => (Bool -> m (Either err a)) -> ParseT err m a
withBool :: (Functor m, Monad m) => (Bool -> Either err a) -> ParseT err m a

-- | Prefer to use functions like <a>key</a> or <a>eachInObject</a> to this
--   one where possible, as they will generate better error messages.
withObjectM :: (Functor m, Monad m) => (Object -> m (Either err a)) -> ParseT err m a

-- | Prefer to use functions like <a>key</a> or <a>eachInObject</a> to this
--   one where possible, as they will generate better error messages.
withObject :: (Functor m, Monad m) => (Object -> Either err a) -> ParseT err m a

-- | Prefer to use functions like <a>nth</a> or <a>eachInArray</a> to this
--   one where possible, as they will generate better error messages.
withArrayM :: (Functor m, Monad m) => (Array -> m (Either err a)) -> ParseT err m a

-- | Prefer to use functions like <a>nth</a> or <a>eachInArray</a> to this
--   one where possible, as they will generate better error messages.
withArray :: (Functor m, Monad m) => (Array -> Either err a) -> ParseT err m a

-- | Throw a custom validation error.
throwCustomError :: (Functor m, Monad m) => err -> ParseT err m a
liftCustomT :: (Functor m, Monad m) => ExceptT err m a -> ParseT err m a
instance GHC.Base.Monad m => Control.Monad.Error.Class.MonadError (Data.Aeson.BetterErrors.Internal.ParseError err) (Data.Aeson.BetterErrors.Internal.ParseT err m)
instance GHC.Base.Monad m => Control.Monad.Reader.Class.MonadReader Data.Aeson.BetterErrors.Internal.ParseReader (Data.Aeson.BetterErrors.Internal.ParseT err m)
instance GHC.Base.Monad m => GHC.Base.Monad (Data.Aeson.BetterErrors.Internal.ParseT err m)
instance GHC.Base.Monad m => GHC.Base.Applicative (Data.Aeson.BetterErrors.Internal.ParseT err m)
instance GHC.Base.Functor m => GHC.Base.Functor (Data.Aeson.BetterErrors.Internal.ParseT err m)
instance GHC.Base.Functor Data.Aeson.BetterErrors.Internal.ParseError
instance GHC.Classes.Eq err => GHC.Classes.Eq (Data.Aeson.BetterErrors.Internal.ParseError err)
instance GHC.Show.Show err => GHC.Show.Show (Data.Aeson.BetterErrors.Internal.ParseError err)
instance GHC.Base.Functor Data.Aeson.BetterErrors.Internal.ErrorSpecifics
instance GHC.Classes.Eq err => GHC.Classes.Eq (Data.Aeson.BetterErrors.Internal.ErrorSpecifics err)
instance GHC.Show.Show err => GHC.Show.Show (Data.Aeson.BetterErrors.Internal.ErrorSpecifics err)
instance GHC.Classes.Ord Data.Aeson.BetterErrors.Internal.JSONType
instance GHC.Classes.Eq Data.Aeson.BetterErrors.Internal.JSONType
instance GHC.Show.Show Data.Aeson.BetterErrors.Internal.JSONType
instance GHC.Classes.Ord Data.Aeson.BetterErrors.Internal.PathPiece
instance GHC.Classes.Eq Data.Aeson.BetterErrors.Internal.PathPiece
instance GHC.Show.Show Data.Aeson.BetterErrors.Internal.PathPiece
instance Control.Monad.Trans.Class.MonadTrans (Data.Aeson.BetterErrors.Internal.ParseT err)


-- | A module for decoding JSON, and generating good error messages. Note,
--   however, that this package only deals with generating good error
--   messages <i>after</i> the JSON has been parsed into a <a>Value</a> -
--   unfortunately, invalid JSON will still produce poor error messages.
--   
--   See <a>http://harry.garrood.me/blog/aeson-better-errors/</a> for a
--   tutorial.
--   
--   Any kind of feedback is very welcome: suggestions for a better
--   designed API, bug reports, whatever - the best place for it is
--   probably the GitHub issue tracker:
--   <a>https://github.com/hdgarrood/aeson-better-errors/issues</a>.
module Data.Aeson.BetterErrors

-- | The type of parsers: things which consume JSON values and produce
--   either detailed errors or successfully parsed values (of other types).
--   
--   The <tt>err</tt> type parameter is for custom validation errors; for
--   parsers that don't produce any custom validation errors, I recommend
--   you just stick a type variable in for full generality:
--   
--   <pre>
--   asTuple :: Parse e (Int, Int)
--   asTuple = (,) &lt;$&gt; nth 0 asIntegral &lt;*&gt; nth 1 asIntegral
--   </pre>
--   
--   The <tt>m</tt> parameter allows you to run the parser within an
--   abitrary underlying Monad. You may want to use <a>Parse</a> in most
--   cases instead, and all functions in this module work on either.
data ParseT err m a

-- | This is the standard version of <a>ParseT</a> over the <a>Identity</a>
--   Monad, for running pure parsers.
type Parse err a = ParseT err Identity a

-- | The type of parsers which never produce custom validation errors.
type Parse' a = Parse Void a

-- | Transform the error of a parser according to the given function.
mapError :: Functor m => (err -> err') -> ParseT err m a -> ParseT err' m a

-- | An infix version of <a>mapError</a>.
(.!) :: Functor m => ParseT err m a -> (err -> err') -> ParseT err' m a

-- | Return the current JSON <a>Value</a> as is. This does no error
--   checking and thus always succeeds. You probably don't want this parser
--   unless the JSON at the current part of your structure is truly
--   arbitrary. You should prefer to use more specific parsers, like
--   <a>asText</a> or <a>asIntegral</a>, where possible.
asValue :: (Functor m, Monad m) => ParseT err m Value

-- | Parse a single JSON string as <a>Text</a>.
asText :: (Functor m, Monad m) => ParseT err m Text

-- | Parse a single JSON string as a <a>String</a>.
asString :: (Functor m, Monad m) => ParseT err m String

-- | Parse a single JSON number as a <a>Scientific</a>.
asScientific :: (Functor m, Monad m) => ParseT err m Scientific

-- | Parse a single JSON number as any <a>Integral</a> type.
asIntegral :: (Functor m, Monad m, Integral a) => ParseT err m a

-- | Parse a single JSON number as any <a>RealFloat</a> type.
asRealFloat :: (Functor m, Monad m, RealFloat a) => ParseT err m a

-- | Parse a single JSON boolean as a <a>Bool</a>.
asBool :: (Functor m, Monad m) => ParseT err m Bool

-- | Parse a single JSON null value. Useful if you want to throw an error
--   in the case where something is not null.
asNull :: (Functor m, Monad m) => ParseT err m ()

-- | Parse a JSON object, as an <a>Object</a>. You should prefer functions
--   like <a>eachInObject</a> where possible, since they will usually
--   generate better error messages.
asObject :: (Functor m, Monad m) => ParseT err m Object

-- | Parse a JSON array, as an <a>Array</a>. You should prefer functions
--   like <a>eachInArray</a> where possible, since they will usually
--   generate better error messages.
asArray :: (Functor m, Monad m) => ParseT err m Array

-- | Given a parser, transform it into a parser which returns
--   <tt>Nothing</tt> when supplied with a JSON <tt>null</tt>, and
--   otherwise, attempts to parse with the original parser; if this
--   succeeds, the result becomes a <tt>Just</tt> value.
perhaps :: (Functor m, Monad m) => ParseT err m a -> ParseT err m (Maybe a)

-- | Take the value corresponding to a given key in the current object.
key :: (Functor m, Monad m) => Text -> ParseT err m a -> ParseT err m a

-- | Take the value corresponding to a given key in the current object, or
--   if no property exists with that key, use the supplied default.
keyOrDefault :: (Functor m, Monad m) => Text -> a -> ParseT err m a -> ParseT err m a

-- | Take the value corresponding to a given key in the current object, or
--   if no property exists with that key, return Nothing .
keyMay :: (Functor m, Monad m) => Text -> ParseT err m a -> ParseT err m (Maybe a)

-- | Take the nth value of the current array.
nth :: (Functor m, Monad m) => Int -> ParseT err m a -> ParseT err m a

-- | Take the nth value of the current array, or if no value exists with
--   that index, use the supplied default.
nthOrDefault :: (Functor m, Monad m) => Int -> a -> ParseT err m a -> ParseT err m a

-- | Take the nth value of the current array, or if no value exists with
--   that index, return Nothing.
nthMay :: (Functor m, Monad m) => Int -> ParseT err m a -> ParseT err m (Maybe a)

-- | Attempt to parse each value in the array with the given parser, and
--   collect the results.
eachInArray :: (Functor m, Monad m) => ParseT err m a -> ParseT err m [a]

-- | Parse each property in an object with the given parser, given the key
--   as an argument, and collect the results.
forEachInObject :: (Functor m, Monad m) => (Text -> ParseT err m a) -> ParseT err m [a]

-- | Attempt to parse each property value in the object with the given
--   parser, and collect the results.
eachInObject :: (Functor m, Monad m) => ParseT err m a -> ParseT err m [(Text, a)]

-- | Attempt to parse each property in the object: parse the key with the
--   given validation function, parse the value with the given parser, and
--   collect the results.
eachInObjectWithKey :: (Functor m, Monad m) => (Text -> Either err k) -> ParseT err m a -> ParseT err m [(k, a)]

-- | Lifts a function attempting to validate an arbitrary JSON value into a
--   parser. You should only use this if absolutely necessary; the other
--   functions in this module will generally give better error reporting.
withValue :: (Functor m, Monad m) => (Value -> Either err a) -> ParseT err m a
withText :: (Functor m, Monad m) => (Text -> Either err a) -> ParseT err m a
withString :: (Functor m, Monad m) => (String -> Either err a) -> ParseT err m a
withScientific :: (Functor m, Monad m) => (Scientific -> Either err a) -> ParseT err m a
withIntegral :: (Functor m, Monad m, Integral a) => (a -> Either err b) -> ParseT err m b
withRealFloat :: (Functor m, Monad m, RealFloat a) => (a -> Either err b) -> ParseT err m b
withBool :: (Functor m, Monad m) => (Bool -> Either err a) -> ParseT err m a

-- | Prefer to use functions like <a>key</a> or <a>eachInObject</a> to this
--   one where possible, as they will generate better error messages.
withObject :: (Functor m, Monad m) => (Object -> Either err a) -> ParseT err m a

-- | Prefer to use functions like <a>nth</a> or <a>eachInArray</a> to this
--   one where possible, as they will generate better error messages.
withArray :: (Functor m, Monad m) => (Array -> Either err a) -> ParseT err m a

-- | Throw a custom validation error.
throwCustomError :: (Functor m, Monad m) => err -> ParseT err m a
withValueM :: (Functor m, Monad m) => (Value -> m (Either err a)) -> ParseT err m a
withTextM :: (Functor m, Monad m) => (Text -> m (Either err a)) -> ParseT err m a
withStringM :: (Functor m, Monad m) => (String -> m (Either err a)) -> ParseT err m a
withScientificM :: (Functor m, Monad m) => (Scientific -> m (Either err a)) -> ParseT err m a
withIntegralM :: (Functor m, Monad m, Integral a) => (a -> m (Either err b)) -> ParseT err m b
withRealFloatM :: (Functor m, Monad m, RealFloat a) => (a -> m (Either err b)) -> ParseT err m b
withBoolM :: (Functor m, Monad m) => (Bool -> m (Either err a)) -> ParseT err m a

-- | Prefer to use functions like <a>key</a> or <a>eachInObject</a> to this
--   one where possible, as they will generate better error messages.
withObjectM :: (Functor m, Monad m) => (Object -> m (Either err a)) -> ParseT err m a

-- | Prefer to use functions like <a>nth</a> or <a>eachInArray</a> to this
--   one where possible, as they will generate better error messages.
withArrayM :: (Functor m, Monad m) => (Array -> m (Either err a)) -> ParseT err m a

-- | Run a parser with a lazy <a>ByteString</a> containing JSON data. Note
--   that the normal caveat applies: the JSON supplied must contain either
--   an object or an array for this to work.
parse :: Parse err a -> ByteString -> Either (ParseError err) a

-- | Run a parser with a strict <a>ByteString</a> containing JSON data.
--   Note that the normal caveat applies: the JSON supplied must contain
--   either an object or an array for this to work.
parseStrict :: Parse err a -> ByteString -> Either (ParseError err) a

-- | Run a parser with a pre-parsed JSON <a>Value</a>.
parseValue :: Parse err a -> Value -> Either (ParseError err) a

-- | Like <a>parse</a> but runs the parser on an arbitrary underlying
--   Monad.
parseM :: Monad m => ParseT err m a -> ByteString -> m (Either (ParseError err) a)

-- | Like <a>parseStrict</a> but runs the parser on an arbitrary underlying
--   Monad.
parseStrictM :: Monad m => ParseT err m a -> ByteString -> m (Either (ParseError err) a)

-- | Like <a>parseValue</a> but runs the parser on an arbitrary underlying
--   Monad.
parseValueM :: Monad m => ParseT err m a -> Value -> m (Either (ParseError err) a)

-- | A value indicating that the JSON could not be decoded successfully.
data ParseError err

-- | Indicates a syntax error in the JSON string. Unfortunately, in this
--   case, Aeson's errors are not very helpful.
InvalidJSON :: String -> ParseError err

-- | Indicates a decoding error; the input was parsed as JSON successfully,
--   but a value of the required type could not be constructed, perhaps
--   because of a missing key or type mismatch.
BadSchema :: [PathPiece] -> (ErrorSpecifics err) -> ParseError err

-- | The type of parse errors which never involve custom validation errors.
type ParseError' = ParseError Void

-- | A piece of a path leading to a specific part of the JSON data.
--   Internally, a list of these is maintained as the parser traverses the
--   JSON data. This list is included in the error if one occurs.
data PathPiece
ObjectKey :: Text -> PathPiece
ArrayIndex :: Int -> PathPiece

-- | Detailed information in the case where a value could be parsed as
--   JSON, but a value of the required type could not be constructed from
--   it, for some reason.
data ErrorSpecifics err
KeyMissing :: Text -> ErrorSpecifics err
OutOfBounds :: Int -> ErrorSpecifics err

-- | Expected type, actual value
WrongType :: JSONType -> Value -> ErrorSpecifics err
ExpectedIntegral :: Double -> ErrorSpecifics err

-- | An error arising inside a <a>FromJSON</a> instance.
FromAeson :: String -> ErrorSpecifics err
CustomError :: err -> ErrorSpecifics err

-- | The type of error specifics which never involve custom validation
--   errors.
type ErrorSpecifics' = ErrorSpecifics Void

-- | Turn a <a>ParseError</a> into a human-readable list of <a>Text</a>
--   values. They will be in a sensible order. For example, you can feed
--   the result to <tt>mapM putStrLn</tt>, or <tt>unlines</tt>.
displayError :: (err -> Text) -> ParseError err -> [Text]

-- | A version of <a>displayError</a> for parsers which do not produce
--   custom validation errors.
displayError' :: ParseError' -> [Text]
displayPath :: [PathPiece] -> Text
displaySpecifics :: (err -> Text) -> ErrorSpecifics err -> [Text]

-- | A version of <a>displaySpecifics</a> for parsers which do not produce
--   custom validation errors.
displaySpecifics' :: ErrorSpecifics' -> [Text]

-- | This function is useful when you have a <tt><a>Parse</a> err a</tt>
--   and you want to obtain an instance for <tt><a>FromJSON</a> a</tt>.
--   Simply define:
--   
--   <pre>
--   parseJSON = toAesonParser showMyCustomError myParser
--   </pre>
toAesonParser :: (err -> Text) -> Parse err a -> Value -> Parser a

-- | Take a parser which never produces custom validation errors and turn
--   it into an Aeson parser. Note that in this case, there is no need to
--   provide a display function.
toAesonParser' :: Parse' a -> Value -> Parser a

-- | Create a parser for any type, using its FromJSON instance. Generally,
--   you should prefer to write parsers using the other functions in this
--   module; <a>key</a>, <a>asString</a>, etc, since they will usually
--   generate better error messages. However this function is also useful
--   occasionally.
fromAesonParser :: (Functor m, Monad m) => FromJSON a => ParseT e m a

-- | An enumeration of the different types that JSON values may take.
data JSONType
TyObject :: JSONType
TyArray :: JSONType
TyString :: JSONType
TyNumber :: JSONType
TyBool :: JSONType
TyNull :: JSONType

-- | Get the type of a JSON value.
jsonTypeOf :: Value -> JSONType
