-- 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.1.0

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

-- | First try the left parser, if that fails try the right. | If both
--   fail, the error will come from the right one.
(<|>) :: Monad m => ParseT err m a -> ParseT err m a -> ParseT err m a
infixl 3 <|>

-- | 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.Enum.Bounded Data.Aeson.BetterErrors.Internal.JSONType
instance GHC.Enum.Enum Data.Aeson.BetterErrors.Internal.JSONType
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

-- | First try the left parser, if that fails try the right. | If both
--   fail, the error will come from the right one.
(<|>) :: Monad m => ParseT err m a -> ParseT err m a -> ParseT err m a
infixl 3 <|>

-- | 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
