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

-- | Command-line interface for the hledger accounting system
--   
--   The command-line interface for the hledger accounting system. Its
--   basic function is to read a plain text file describing financial
--   transactions and produce useful reports.
--   
--   hledger is a robust, cross-platform set of tools for tracking money,
--   time, or any other commodity, using double-entry accounting and a
--   simple, editable file format, with command-line, terminal and web
--   interfaces. It is a Haskell rewrite of Ledger, and one of the leading
--   implementations of Plain Text Accounting. Read more at:
--   https://hledger.org
@package hledger
@version 1.32.3

-- | Instances for obfuscating sensitive data (mainly text, not numbers) in
--   various types.
--   
--   Currently this is deterministic and does not provide much privacy. It
--   has been moved to a hidden --obfuscate flag, with the old --anon flag
--   now raising an error. See
--   https://github.com/simonmichael/hledger/issues/2133 .
module Hledger.Cli.Anon
class Anon a

-- | Consistent converter to structure with sensitive data anonymized
anon :: Anon a => a -> a

-- | Anonymize account name preserving hierarchy
anonAccount :: AccountName -> AccountName
instance Hledger.Cli.Anon.Anon Hledger.Data.Types.Journal
instance Hledger.Cli.Anon.Anon Hledger.Data.Types.Posting
instance Hledger.Cli.Anon.Anon Hledger.Data.Types.Transaction
instance Hledger.Cli.Anon.Anon Data.Text.Internal.Text

-- | Embedded documentation files in various formats, and helpers for
--   viewing them.
--   
--   |
module Hledger.Cli.DocFiles
type Topic = String

-- | Print plain text help for this tool. Takes an optional topic argument
--   for convenience but it is currently ignored.
printHelpForTopic :: Tool -> Maybe Topic -> IO ()

-- | Display a man page for this tool, scrolled to the given topic if
--   provided, using the "man" executable in $PATH. Note when a topic is
--   provided we force man to use the "less" executable in $PATH, ignoring
--   $MANPAGER and $PAGER.
runManForTopic :: Tool -> Maybe Topic -> IO ()

-- | Display an info manual for this topic, opened at the given topic if
--   provided, using the "info" executable in $PATH.
runInfoForTopic :: Tool -> Maybe Topic -> IO ()

-- | Display plain text help for this tool, scrolled to the given topic if
--   provided, using the given pager executable. Note when a topic is
--   provided we ignore the provided pager and use the "less" executable in
--   $PATH.
runPagerForTopic :: Tool -> Maybe Topic -> IO ()

module Hledger.Cli.Version
type ProgramName = String
type PackageVersion = String
type VersionString = String

-- | The "1.32.3" string defined with -D in this package's
--   package.yaml/.cabal file (by Shake setversion), if any. Normally a
--   dotted number string with 1-3 components.
packageversion :: PackageVersion

-- | Just the first 1-2 components of packageversion.
packagemajorversion :: PackageVersion

-- | The name of this package's main executable.
progname :: ProgramName

-- | Given possible git state info from the build directory (or an error
--   message, which is ignored), the name of a program (executable) in the
--   currently building package, and the package's version, make a complete
--   version string. Here is the logic:
--   
--   
--   
- Program name, OS and architecture are always shown.
--   
- The package version is always shown.
--   
- If there is git info at build time, the latest commit hash and
--   commit date are shown, and (TODO, requires githash to use -uno for
--   giDirty): if the working copy has uncommitted changes a + sign is
--   appended.
--   
- (TODO, requires adding --match support to githash: If there are
--   tags matching THISPKG-[0-9]*, the latest one is used to calculate
--   patch level (number of commits since tag), and if non-zero, it and the
--   branch name are shown.)
--   
--   
--   Some example outputs:
--   
--   
--   
- A homebrew binary, not built in git repo: hledger-ui 1.24,
--   mac-aarch64
--   
- A CI release build, built in git repo at release tag: hledger-ui
--   1.24.1-g455b35293-20211210, mac-x86_64
--   
- (TODO) A dev build, built in git repo: hledger-ui
--   1.24.1+1-g4abd8ef10-20211210 (1.24-branch), mac-x86_64
--   
--   
--   This function requires git log to show the default (rfc2822-style)
--   date format, so that must not be overridden by a log.date git config
--   variable.
versionStringWith :: Either String GitInfo -> ProgramName -> PackageVersion -> VersionString

-- | Common cmdargs modes and flags, a command-line options type, and
--   related utilities used by hledger commands.
module Hledger.Cli.CliOptions

-- | Common help flags: --help, --debug, --version...
helpflags :: [Flag RawOpts]

-- | A hidden flag just for the hledger executable.
detailedversionflag :: Flag RawOpts

-- | Flags for selecting flat/tree mode, used for reports organised by
--   account. With a True argument, shows some extra help about
--   inclusive/exclusive amounts.
flattreeflags :: Bool -> [Flag RawOpts]

-- | Common flags that are accepted but not shown in --help, such as
--   --effective, --aux-date.
hiddenflags :: [Flag RawOpts]

-- | Common input-related flags: --file, --rules-file, --alias...
inputflags :: [Flag RawOpts]

-- | Common report-related flags: --period, --cost, etc.
reportflags :: [Flag RawOpts]

-- | Common output-related flags: --output-file, --output-format...
outputFormatFlag :: [String] -> Flag RawOpts
outputFileFlag :: Flag RawOpts
generalflagsgroup1 :: (String, [Flag RawOpts])
generalflagsgroup2 :: (String, [Flag RawOpts])
generalflagsgroup3 :: (String, [Flag RawOpts])

-- | An empty cmdargs mode to use as a template. Modes describe the
--   top-level command, ie the program, or a subcommand, telling cmdargs
--   how to parse a command line and how to generate the command's usage
--   text.
defMode :: Mode RawOpts

-- | A cmdargs mode suitable for a hledger built-in command with the given
--   names (primary name + optional aliases). The usage message shows
--   [QUERY] as argument.
defCommandMode :: [Name] -> Mode RawOpts

-- | A cmdargs mode representing the hledger add-on command with the given
--   name, providing hledger's common inputreportinghelp flags. Just
--   used when invoking addons.
addonCommandMode :: Name -> Mode RawOpts

-- | Build a cmdarg mode for a hledger command, from a help template and
--   flag/argument specifications. Reduces boilerplate a little, though the
--   complicated cmdargs flag and argument specs are still required.
hledgerCommandMode :: CommandDoc -> [Flag RawOpts] -> [(String, [Flag RawOpts])] -> [Flag RawOpts] -> ([Arg RawOpts], Maybe (Arg RawOpts)) -> Mode RawOpts
argsFlag :: FlagHelp -> Arg RawOpts

-- | Get a mode's usage message as a nicely wrapped string.
showModeUsage :: Mode a -> String

-- | Add command aliases to the command's help string.
withAliases :: String -> [String] -> String

-- | Get all sorted unique filenames in the current user's PATH. We do not
--   currently filter out non-file objects or files without execute
--   permission.
likelyExecutablesInPath :: IO [String]

-- | Get the sorted unique filenames of all hledger-* executables in the
--   current user's PATH. These are files in any of the PATH directories,
--   named hledger-*, with either no extension (and no periods in the name)
--   or one of the addonExtensions. We do not currently filter out non-file
--   objects or files without execute permission.
hledgerExecutablesInPath :: IO [String]

-- | Convert an argument-less --debug flag to --debug=1 in the given
--   arguments list. Used by hledgeruiweb to make their command line
--   parsing easier somehow.
ensureDebugHasArg :: (Eq (t Char), IsString (t Char), Foldable t) => [t Char] -> [t Char]

-- | Command line options, used in the hledger package and above.
--   This is the "opts" used throughout hledger CLI code. representing the
--   options and arguments that were provided at startup on the
--   command-line.
data CliOpts
CliOpts :: RawOpts -> String -> [FilePath] -> InputOpts -> ReportSpec -> Maybe FilePath -> Maybe String -> Int -> Bool -> Maybe String -> Int -> POSIXTime -> CliOpts
[rawopts_] :: CliOpts -> RawOpts
[command_] :: CliOpts -> String
[file_] :: CliOpts -> [FilePath]
[inputopts_] :: CliOpts -> InputOpts
[reportspec_] :: CliOpts -> ReportSpec
[output_file_] :: CliOpts -> Maybe FilePath
[output_format_] :: CliOpts -> Maybe String

-- | debug level, set by --debug[=N]. See also debugLevel.
[debug_] :: CliOpts -> Int
[no_new_accounts_] :: CliOpts -> Bool

-- | the --width value provided, if any
[width_] :: CliOpts -> Maybe String

-- | estimated usable screen width, based on 1. the COLUMNS env var, if set
--   2. the width reported by the terminal, if supported 3. the default
--   (80)
[available_width_] :: CliOpts -> Int
[progstarttime_] :: CliOpts -> POSIXTime
class HasCliOpts c_ahMj
cliOpts :: HasCliOpts c_ahMj => Lens' c_ahMj CliOpts
available_width :: HasCliOpts c_ahMj => Lens' c_ahMj Int
command :: HasCliOpts c_ahMj => Lens' c_ahMj String
debug__ :: HasCliOpts c_ahMj => Lens' c_ahMj Int
file__ :: HasCliOpts c_ahMj => Lens' c_ahMj [FilePath]
inputopts :: HasCliOpts c_ahMj => Lens' c_ahMj InputOpts
no_new_accounts :: HasCliOpts c_ahMj => Lens' c_ahMj Bool
output_file :: HasCliOpts c_ahMj => Lens' c_ahMj (Maybe FilePath)
output_format :: HasCliOpts c_ahMj => Lens' c_ahMj (Maybe String)
progstarttime :: HasCliOpts c_ahMj => Lens' c_ahMj POSIXTime
rawopts__ :: HasCliOpts c_ahMj => Lens' c_ahMj RawOpts
reportspec :: HasCliOpts c_ahMj => Lens' c_ahMj ReportSpec
width__ :: HasCliOpts c_ahMj => Lens' c_ahMj (Maybe String)
defcliopts :: CliOpts
getHledgerCliOpts :: Mode RawOpts -> IO CliOpts

-- | A helper for addon commands: this parses options and arguments from
--   the current command line using the given hledger-style cmdargs mode,
--   and returns a CliOpts. Or, with --help or -h present, it prints long
--   or short help, and exits the program. When --debug is present, also
--   prints some debug output. Note this is not used by the main hledger
--   executable.
--   
--   The help texts are generated from the mode. Long help includes the
--   full usage description generated by cmdargs (including all supported
--   options), framed by whatever pre- and postamble text the mode
--   specifies. It's intended that this forms a complete help document or
--   manual.
--   
--   Short help is a truncated version of the above: the preamble and the
--   first part of the usage, up to the first line containing "flags:"
--   (normally this marks the start of the common hledger flags); plus a
--   mention of --help and the (presumed supported) common hledger options
--   not displayed.
--   
--   Tips: Empty lines in the pre/postamble are removed by cmdargs; add a
--   space character to preserve them.
getHledgerCliOpts' :: Mode RawOpts -> [String] -> IO CliOpts

-- | Parse raw option string values to the desired final data types. Any
--   relative smart dates will be converted to fixed dates based on today's
--   date. Parsing failures will raise an error. Also records the terminal
--   width, if supported.
rawOptsToCliOpts :: RawOpts -> IO CliOpts

-- | All the output formats known by any command, for outputFormatFromOpts.
--   To automatically infer it from -o/--output-file, it needs to be listed
--   here.
outputFormats :: [String]
defaultOutputFormat :: String

-- | A command's documentation. Used both as part of CLI help, and as part
--   of the hledger manual. See parseCommandDoc.
type CommandDoc = String

-- | Get the (tilde-expanded, absolute) journal file path from 1. options,
--   2. an environment variable, or 3. the default. Actually, returns one
--   or more file paths. There will be more than one if multiple -f options
--   were provided. File paths can have a READER: prefix naming a
--   reader/data format.
journalFilePathFromOpts :: CliOpts -> IO [String]

-- | Get the (tilde-expanded) rules file path from options, if any.
rulesFilePathFromOpts :: CliOpts -> IO (Maybe FilePath)

-- | Get the expanded, absolute output file path specified by an
--   -o/--output-file options, or nothing, meaning stdout.
outputFileFromOpts :: CliOpts -> IO (Maybe FilePath)

-- | Get the output format from the --output-format option, otherwise from
--   a recognised file extension in the --output-file option, otherwise the
--   default (txt).
outputFormatFromOpts :: CliOpts -> String

-- | Default width for hledger console output, when not otherwise
--   specified.
defaultWidth :: Int

-- | Replace any numeric flags (eg -2) with their long form (--depth 2), as
--   I'm guessing cmdargs doesn't support this directly.
replaceNumericFlags :: [String] -> [String]

-- | Get the width in characters to use for the register command's console
--   output, and also the description column width if specified (following
--   the main width, comma-separated). The widths will be as follows: 
--   no --width flag - overall width is the available width (COLUMNS, or
--   posix terminal width, or 80); description width is unspecified (auto)
--   --width W - overall width is W, description width is auto --width W,D
--   - overall width is W, description width is D  Will raise a parse
--   error for a malformed --width argument.
registerWidthsFromOpts :: CliOpts -> (Int, Maybe Int)

-- | Get the sorted unique canonical names of hledger addon commands found
--   in the current user's PATH. These are used in command line parsing and
--   to display the commands list.
--   
--   Canonical addon names are the filenames of hledger-* executables in
--   PATH, without the "hledger-" prefix, and without the file extension
--   except when it's needed for disambiguation (see below).
--   
--   When there are exactly two versions of an executable (same base name,
--   different extensions) that look like a source and compiled pair (one
--   has .exe, .com, or no extension), the source version will be excluded
--   (even if it happens to be newer). When there are three or more
--   versions (or two versions that don't look like a source/compiled
--   pair), they are all included, with file extensions intact.
hledgerAddons :: IO [String]

-- | Get the most appropriate documentation topic for a mode. Currently,
--   that is either the hledger, hledger-ui or hledger-web manual.
topicForMode :: Mode a -> Topic
instance Hledger.Cli.CliOptions.HasCliOpts Hledger.Cli.CliOptions.CliOpts
instance Hledger.Read.InputOptions.HasInputOpts Hledger.Cli.CliOptions.CliOpts
instance Hledger.Reports.ReportOptions.HasReportSpec Hledger.Cli.CliOptions.CliOpts
instance Hledger.Data.Balancing.HasBalancingOpts Hledger.Cli.CliOptions.CliOpts
instance Hledger.Reports.ReportOptions.HasReportOptsNoUpdate Hledger.Cli.CliOptions.CliOpts
instance Hledger.Reports.ReportOptions.HasReportOpts Hledger.Cli.CliOptions.CliOpts
instance GHC.Show.Show Hledger.Cli.CliOptions.CliOpts
instance Data.Default.Class.Default Hledger.Cli.CliOptions.CliOpts

-- | Utilities for top-level modules and ghci. See also Hledger.Read and
--   Hledger.Utils.
module Hledger.Cli.Utils

-- | Standard error message for a bad output format specified with -O/-o.
unsupportedOutputFormatError :: String -> String

-- | Parse the user's specified journal file(s) as a Journal, maybe apply
--   some transformations according to options, and run a hledger command
--   with it. Or, throw an error.
withJournalDo :: CliOpts -> (Journal -> IO a) -> IO a

-- | Write some output to stdout or to a file selected by --output-file. If
--   the file exists it will be overwritten.
writeOutput :: CliOpts -> String -> IO ()

-- | Write some output to stdout or to a file selected by --output-file. If
--   the file exists it will be overwritten. This function operates on Lazy
--   Text values.
writeOutputLazyText :: CliOpts -> Text -> IO ()

-- | Apply some extra post-parse transformations to the journal, if enabled
--   by options. These happen after parsing and finalising the journal, but
--   before report calculation. They are, in processing order:
--   
--   
--   
- pivoting account names (--pivot)
--   
- anonymising (--anonymise).
--   
journalTransform :: CliOpts -> Journal -> Journal

-- | Re-read the journal file(s) specified by options, applying any
--   transformations specified by options. Or return an error string. Reads
--   the full journal, without filtering.
journalReload :: CliOpts -> ExceptT String IO Journal

-- | Re-read the option-specified journal file(s), but only if any of them
--   has changed since last read. (If the file is standard input, this will
--   either do nothing or give an error, not tested yet). Returns a journal
--   or error message, and a flag indicating whether it was re-read or not.
--   Like withJournalDo and journalReload, reads the full journal, without
--   filtering.
journalReloadIfChanged :: CliOpts -> Day -> Journal -> ExceptT String IO (Journal, Bool)

-- | Has the specified file changed since the journal was last read ?
--   Typically this is one of the journal's journalFilePaths. These are not
--   always real files, so the file's existence is tested first; for
--   non-files the answer is always no.
journalFileIsNewer :: Journal -> FilePath -> IO Bool

-- | Attempt to open a web browser on the given url, all platforms.
openBrowserOn :: String -> IO ExitCode

-- | Back up this file with a (incrementing) numbered suffix, then
--   overwrite it with this new text, or give an error.
writeFileWithBackup :: FilePath -> String -> IO ()

-- | Back up this file with a (incrementing) numbered suffix then overwrite
--   it with this new text, or give an error, but only if the text is
--   different from the current file contents, and return a flag indicating
--   whether we did anything.
--   
--   The given text should have unix line endings (n); the existing file
--   content will be normalised to unix line endings before comparing the
--   two. If the file is overwritten, the new file will have the current
--   system's native line endings (n on unix, rn on windows). This could be
--   different from the file's previous line endings, if working with a DOS
--   file on unix or vice-versa.
writeFileWithBackupIfChanged :: FilePath -> Text -> IO Bool

-- | Apply the pivot transformation on a journal (replacing account names
--   by a different field's value), if option is present.
pivotByOpts :: CliOpts -> Journal -> Journal

-- | Raise an error, announcing the rename to --obfuscate and its
--   limitations.
anonymiseByOpts :: CliOpts -> Journal -> Journal
journalSimilarTransaction :: CliOpts -> Journal -> Text -> Maybe Transaction

-- | Render a PostingsReport or AccountTransactionsReport as
--   Text, determining the appropriate starting widths and increasing as
--   necessary.
postingsOrTransactionsReportAsText :: Bool -> CliOpts -> (Int -> Int -> (a, [WideBuilder], [WideBuilder]) -> Builder) -> (a -> MixedAmount) -> (a -> MixedAmount) -> [a] -> Builder
tests_Cli_Utils :: TestTree

module Hledger.Cli.Commands.Tags
tagsmode :: Mode RawOpts
tags :: CliOpts -> Journal -> IO ()

-- | Print some statistics for the journal.
module Hledger.Cli.Commands.Stats
statsmode :: Mode RawOpts

-- | Print various statistics for the journal.
stats :: CliOpts -> Journal -> IO ()

-- | The roi command prints internal rate of return and
--   time-weighted rate of return for and investment.
module Hledger.Cli.Commands.Roi
roimode :: Mode RawOpts
roi :: CliOpts -> Journal -> IO ()
instance GHC.Show.Show Hledger.Cli.Commands.Roi.OneSpan

-- | A ledger-compatible register command.
module Hledger.Cli.Commands.Register
registermode :: Mode RawOpts

-- | Print a (posting) register report.
register :: CliOpts -> Journal -> IO ()

-- | Render a register report as plain text suitable for console output.
postingsReportAsText :: CliOpts -> PostingsReport -> Text

-- | Render one register report line item as plain text. Layout is like so:
--    width (specified, terminal width, or 80)
--   -------------------- date (10) description account amount (12)
--   balance (12) DDDDDDDDDD dddddddddddddddddddd aaaaaaaaaaaaaaaaaaa
--   AAAAAAAAAAAA AAAAAAAAAAAA  If description's width is specified,
--   account will use the remaining space. Otherwise, description and
--   account divide up the space equally.
--   
--   With a report interval, the layout is like so:  width
--   (specified, terminal width, or 80) -------------------- date (21)
--   account amount (12) balance (12) DDDDDDDDDDDDDDDDDDDDD
--   aaaaaaaaaaaaaaaaaaaaaaaaaaaaa AAAAAAAAAAAA AAAAAAAAAAAA 
--   
--   date and description are shown for the first posting of a transaction
--   only.
--   
--   Returns a string which can be multi-line, eg if the running balance
--   has multiple commodities. Does not yet support formatting control like
--   balance reports.
--   
--   Also returns the natural width (without padding) of the amount and
--   balance fields.
postingsReportItemAsText :: CliOpts -> Int -> Int -> (PostingsReportItem, [WideBuilder], [WideBuilder]) -> Builder
tests_Register :: TestTree

-- | A ledger-compatible print command.
module Hledger.Cli.Commands.Print
printmode :: Mode RawOpts

-- | Print journal transactions in standard format.
print' :: CliOpts -> Journal -> IO ()

-- | Replace this transaction's postings with the original postings if any,
--   but keep the current possibly rewritten account names, and the
--   inferred values of any auto postings. This is mainly for showing
--   transactions with the amounts in their original journal format.
transactionWithMostlyOriginalPostings :: Transaction -> Transaction

module Hledger.Cli.Commands.Rewrite
rewritemode :: Mode RawOpts
rewrite :: CliOpts -> Journal -> IO ()
instance Data.Traversable.Traversable Hledger.Cli.Commands.Rewrite.DiffLine
instance Data.Foldable.Foldable Hledger.Cli.Commands.Rewrite.DiffLine
instance GHC.Base.Functor Hledger.Cli.Commands.Rewrite.DiffLine
instance GHC.Show.Show a => GHC.Show.Show (Hledger.Cli.Commands.Rewrite.DiffLine a)

module Hledger.Cli.Commands.Prices
pricesmode :: Mode RawOpts
prices :: CliOpts -> Journal -> IO ()
instance Hledger.Data.Types.HasAmounts Hledger.Data.Types.PriceDirective

-- | The payees command lists all unique payees (description part
--   before a |) seen in transactions, sorted alphabetically.
module Hledger.Cli.Commands.Payees

-- | Command line options for this command.
payeesmode :: Mode RawOpts

-- | The payees command.
payees :: CliOpts -> Journal -> IO ()

-- | The notes command lists all unique notes (description part
--   after a |) seen in transactions, sorted alphabetically.
module Hledger.Cli.Commands.Notes

-- | Command line options for this command.
notesmode :: Mode RawOpts

-- | The notes command.
notes :: CliOpts -> Journal -> IO ()

-- | The help command.
--   
--   |
module Hledger.Cli.Commands.Help
helpmode :: Mode RawOpts

-- | Display the hledger manual in various formats. You can select a docs
--   viewer with one of the `--info`, `--man`, `--pager` flags. Otherwise
--   it will use the first available of: info, man, $PAGER, less, stdout
--   (and always stdout if output is non-interactive).
help' :: CliOpts -> Journal -> IO ()

-- | The files command lists included files.
module Hledger.Cli.Commands.Files

-- | Command line options for this command.
filesmode :: Mode RawOpts

-- | The files command.
files :: CliOpts -> Journal -> IO ()

-- | The diff command compares two diff.
module Hledger.Cli.Commands.Diff

-- | Command line options for this command.
diffmode :: Mode RawOpts

-- | The diff command.
diff :: CliOpts -> Journal -> IO ()
instance GHC.Show.Show Hledger.Cli.Commands.Diff.PostingWithPath
instance GHC.Classes.Eq Hledger.Cli.Commands.Diff.PostingWithPath

-- | The descriptions command lists all unique descriptions seen
--   in transactions, sorted alphabetically.
module Hledger.Cli.Commands.Descriptions

-- | Command line options for this command.
descriptionsmode :: Mode RawOpts

-- | The descriptions command.
descriptions :: CliOpts -> Journal -> IO ()

-- | The demo command lists and plays small hledger demos in the
--   terminal, using asciinema.
module Hledger.Cli.Commands.Demo

-- | Command line options for this command.
demomode :: Mode RawOpts

-- | The demo command.
demo :: CliOpts -> Journal -> IO ()

-- | The commodities command lists commodity/currency symbols.
module Hledger.Cli.Commands.Commodities

-- | Command line options for this command.
commoditiesmode :: Mode RawOpts
commodities :: CliOpts -> Journal -> IO ()

-- | The codes command lists the codes seen in transactions, in
--   the order parsed.
module Hledger.Cli.Commands.Codes

-- | Command line options for this command.
codesmode :: Mode RawOpts

-- | The codes command.
codes :: CliOpts -> Journal -> IO ()

module Hledger.Cli.Commands.Close
closemode :: Mode RawOpts
close :: CliOpts -> Journal -> IO ()

module Hledger.Cli.Commands.Check
checkmode :: Mode RawOpts
check :: CliOpts -> Journal -> IO ()
instance GHC.Enum.Bounded Hledger.Cli.Commands.Check.Check
instance GHC.Enum.Enum Hledger.Cli.Commands.Check.Check
instance GHC.Classes.Eq Hledger.Cli.Commands.Check.Check
instance GHC.Show.Show Hledger.Cli.Commands.Check.Check
instance GHC.Read.Read Hledger.Cli.Commands.Check.Check

-- | A ledger-compatible balance command, with additional support
--   for multi-column reports.
--   
--   Here is a description/specification for the balance command. See also
--   Hledger.Reports -> "Balance reports".
--   
--   Basic balance report
--   
--   With no report interval (--monthly etc.), hledger's balance
--   command emulates ledger's, showing accounts indented according to
--   hierarchy, along with their total amount posted (including
--   subaccounts).
--   
--   Here's an example. With examples/sample.journal, which
--   defines the following account tree:
--   
--   
--   assets
--     bank
--       checking
--       saving
--     cash
--   expenses
--     food
--     supplies
--   income
--     gifts
--     salary
--   liabilities
--     debts
--   
--   
--   the basic balance command gives this output:
--   
--   
--    $ hledger -f sample.journal balance
--                    $-1  assets
--                     $1    bank:saving
--                    $-2    cash
--                     $2  expenses
--                     $1    food
--                     $1    supplies
--                    $-2  income
--                    $-1    gifts
--                    $-1    salary
--                     $1  liabilities:debts
--   --------------------
--                      0
--   
--   
--   Subaccounts are displayed indented below their parent. Only the
--   account leaf name (the final part) is shown. (With --flat,
--   account names are shown in full and unindented.)
--   
--   Each account's "balance" is the sum of postings in that account and
--   any subaccounts during the report period. When the report period
--   includes all transactions, this is equivalent to the account's current
--   balance.
--   
--   The overall total of the highest-level displayed accounts is shown
--   below the line. (The --no-total/-N flag prevents this.)
--   
--   Eliding and omitting
--   
--   Accounts which have a zero balance, and no non-zero subaccount
--   balances, are normally omitted from the report. (The
--   --empty/-E flag forces such accounts to be displayed.) Eg,
--   above checking is omitted because it has a zero balance and
--   no subaccounts.
--   
--   Accounts which have a single subaccount also being displayed, with the
--   same balance, are normally elided into the subaccount's line. (The
--   --no-elide flag prevents this.) Eg, above bank is
--   elided to bank:saving because it has only a single displayed
--   subaccount (saving) and their balance is the same ($1).
--   Similarly, liabilities is elided to
--   liabilities:debts.
--   
--   Date limiting
--   
--   The default report period is that of the whole journal, including all
--   known transactions. The --begin/-b, --end/-e,
--   --period/-p options or date:/date2:
--   patterns can be used to report only on transactions before and/or
--   after specified dates.
--   
--   Depth limiting
--   
--   The --depth option can be used to limit the depth of the
--   balance report. Eg, to see just the top level accounts (still
--   including their subaccount balances):
--   
--   
--   $ hledger -f sample.journal balance --depth 1
--                    $-1  assets
--                     $2  expenses
--                    $-2  income
--                     $1  liabilities
--   --------------------
--                      0
--   
--   
--   Account limiting
--   
--   With one or more account pattern arguments, the report is restricted
--   to accounts whose name matches one of the patterns, plus their parents
--   and subaccounts. Eg, adding the pattern o to the first
--   example gives:
--   
--   
--    $ hledger -f sample.journal balance o
--                     $1  expenses:food
--                    $-2  income
--                    $-1    gifts
--                    $-1    salary
--   --------------------
--                    $-1
--   
--   
--   
--   
- The o pattern matched food and income,
--   so they are shown.
--   
- food's parent (expenses) is shown even though
--   the pattern didn't match it, to clarify the hierarchy. The usual
--   eliding rules cause it to be elided here.
--   
- income's subaccounts are also shown.
--   
--   
--   Multi-column balance report
--   
--   hledger's balance command will show multiple columns when a reporting
--   interval is specified (eg with --monthly), one column for
--   each sub-period.
--   
--   There are three accumulation strategies for multi-column balance
--   report, indicated by the heading:
--   
--   
--   
- A "period balance" (or "flow") report (with --change, the
--   default) shows the change of account balance in each period, which is
--   equivalent to the sum of postings in each period. Here, checking's
--   balance increased by 10 in Feb:
--   
--   
--   
--   Change of balance (flow):
--   
--                    Jan   Feb   Mar
--   assets:checking   20    10    -5
--   
--   
--   
--   
- A "cumulative balance" report (with --cumulative) shows
--   the accumulated ending balance across periods, starting from zero at
--   the report's start date. Here, 30 is the sum of checking postings
--   during Jan and Feb:
--   
--   
--   
--   Ending balance (cumulative):
--   
--                    Jan   Feb   Mar
--   assets:checking   20    30    25
--   
--   
--   
--   
- A "historical balance" report (with --historical/-H) also
--   shows ending balances, but it includes the starting balance from any
--   postings before the report start date. Here, 130 is the balance from
--   all checking postings at the end of Feb, including pre-Jan postings
--   which created a starting balance of 100:
--   
--   
--   
--   Ending balance (historical):
--   
--                    Jan   Feb   Mar
--   assets:checking  120   130   125
--   
--   
--   Eliding and omitting, 2
--   
--   Here's a (imperfect?) specification for the eliding/omitting
--   behaviour:
--   
--   
--   
- Each account is normally displayed on its own line.
--   
- An account less deep than the report's max depth, with just one
--   interesting subaccount, and the same balance as the subaccount, is
--   non-interesting, and prefixed to the subaccount's line, unless
--   --no-elide is in effect.
--   
- An account with a zero inclusive balance and less than two
--   interesting subaccounts is not displayed at all, unless
--   --empty is in effect.
--   
- Multi-column balance reports show full account names with no
--   eliding (like --flat). Accounts (and periods) are omitted as
--   described below.
--   
--   
--   Which accounts to show in balance reports
--   
--   By default:
--   
--   
--   
- single-column: accounts with non-zero balance in report period.
--   (With --flat: accounts with non-zero balance and
--   postings.)
--   
- change: accounts with postings and non-zero period balance in any
--   period
--   
- cumulative: accounts with non-zero cumulative balance in any
--   period
--   
- historical: accounts with non-zero historical balance in any
--   period
--   
--   
--   With -E/--empty:
--   
--   
--   
- single-column: accounts with postings in report period
--   
- change: accounts with postings in report period
--   
- cumulative: accounts with postings in report period
--   
- historical: accounts with non-zero starting balance + accounts
--   with postings in report period
--   
--   
--   Which periods (columns) to show in balance reports
--   
--   An empty period/column is one where no report account has any
--   postings. A zero period/column is one where no report account has a
--   non-zero period balance.
--   
--   Currently,
--   
--   by default:
--   
--   
--   
- single-column: N/A
--   
- change: all periods within the overall report period, except for
--   leading and trailing empty periods
--   
- cumulative: all periods within the overall report period, except
--   for leading and trailing empty periods
--   
- historical: all periods within the overall report period, except
--   for leading and trailing empty periods
--   
--   
--   With -E/--empty:
--   
--   
--   
- single-column: N/A
--   
- change: all periods within the overall report period
--   
- cumulative: all periods within the overall report period
--   
- historical: all periods within the overall report period
--   
--   
--   What to show in empty cells
--   
--   An empty periodic balance report cell is one which has no
--   corresponding postings. An empty cumulative/historical balance report
--   cell is one which has no corresponding or prior postings, ie the
--   account doesn't exist yet. Currently, empty cells show 0.
module Hledger.Cli.Commands.Balance

-- | Command line options for this command.
balancemode :: Mode RawOpts

-- | The balance command, prints a balance report.
balance :: CliOpts -> Journal -> IO ()

-- | Render a single-column balance report as plain text.
balanceReportAsText :: ReportOpts -> BalanceReport -> Builder

-- | Render a single-column balance report as CSV.
balanceReportAsCsv :: ReportOpts -> BalanceReport -> CSV

-- | Render one balance report line item as plain text suitable for console
--   output (or whatever string format is specified). Note, prices will not
--   be rendered, and differently-priced quantities of the same commodity
--   will appear merged. The output will be one or more lines depending on
--   the format and number of commodities.
balanceReportItemAsText :: ReportOpts -> BalanceReportItem -> (Builder, [Int])
multiBalanceRowAsCsvText :: ReportOpts -> [DateSpan] -> PeriodicReportRow a MixedAmount -> [[Text]]
multiBalanceRowAsTableText :: ReportOpts -> PeriodicReportRow a MixedAmount -> [[WideBuilder]]

-- | Render a multi-column balance report as plain text suitable for
--   console output.
multiBalanceReportAsText :: ReportOpts -> MultiBalanceReport -> Text

-- | Render a multi-column balance report as CSV. The CSV will always
--   include the initial headings row, and will include the final totals
--   row unless --no-total is set.
multiBalanceReportAsCsv :: ReportOpts -> MultiBalanceReport -> CSV

-- | Render a multi-column balance report as HTML.
multiBalanceReportAsHtml :: ReportOpts -> MultiBalanceReport -> Html ()

-- | Render the HTML table rows for a MultiBalanceReport. Returns the
--   heading row, 0 or more body rows, and the totals row if enabled.
multiBalanceReportHtmlRows :: ReportOpts -> MultiBalanceReport -> (Html (), [Html ()], [Html ()])

-- | Render one MultiBalanceReport totals row as a HTML table row.
multiBalanceReportHtmlFootRow :: ReportOpts -> [Text] -> Html ()

-- | Build a Table from a multi-column balance report.
balanceReportAsTable :: ReportOpts -> MultiBalanceReport -> Table Text Text WideBuilder

-- | Given a table representing a multi-column balance report (for example,
--   made using balanceReportAsTable), render it in a format
--   suitable for console output. Amounts with more than two commodities
--   will be elided unless --no-elide is used.
balanceReportTableAsText :: ReportOpts -> Table Text Text WideBuilder -> Builder
tests_Balance :: TestTree

-- | Common helpers for making multi-section balance report commands like
--   balancesheet, cashflow, and incomestatement.
module Hledger.Cli.CompoundBalanceCommand

-- | Description of a compound balance report command, from which we
--   generate the command's cmdargs mode and IO action. A compound balance
--   report command shows one or more sections/subreports, each with its
--   own title and subtotals row, in a certain order, plus a grand totals
--   row if there's more than one section. Examples are the balancesheet,
--   cashflow and incomestatement commands.
--   
--   Compound balance reports do sign normalisation: they show all account
--   balances as normally positive, unlike the ordinary BalanceReport and
--   most hledger commands which show incomeliabilityequity balances
--   as normally negative. Each subreport specifies the normal sign of its
--   amounts, and whether it should be added to or subtracted from the
--   grand total.
data CompoundBalanceCommandSpec
CompoundBalanceCommandSpec :: CommandDoc -> String -> [CBCSubreportSpec DisplayName] -> BalanceAccumulation -> CompoundBalanceCommandSpec

-- | the command's name(s) and documentation
[cbcdoc] :: CompoundBalanceCommandSpec -> CommandDoc

-- | overall report title
[cbctitle] :: CompoundBalanceCommandSpec -> String

-- | subreport details
[cbcqueries] :: CompoundBalanceCommandSpec -> [CBCSubreportSpec DisplayName]

-- | how to accumulate balances (per-period, cumulative, historical)
--   (overrides command line flags)
[cbcaccum] :: CompoundBalanceCommandSpec -> BalanceAccumulation

-- | Generate a cmdargs option-parsing mode from a compound balance command
--   specification.
compoundBalanceCommandMode :: CompoundBalanceCommandSpec -> Mode RawOpts

-- | Generate a runnable command from a compound balance command
--   specification.
compoundBalanceCommand :: CompoundBalanceCommandSpec -> CliOpts -> Journal -> IO ()

-- | The incomestatement command prints a simple income statement
--   (profit & loss report).
module Hledger.Cli.Commands.Incomestatement
incomestatementmode :: Mode RawOpts
incomestatement :: CliOpts -> Journal -> IO ()

-- | The cashflow command prints a simplified cashflow statement.
--   It just shows the change in all "cash" accounts for the period
--   (without the traditional segmentation into operating, investing, and
--   financing cash flows.)
module Hledger.Cli.Commands.Cashflow
cashflowmode :: Mode RawOpts
cashflow :: CliOpts -> Journal -> IO ()

-- | The balancesheetequity command prints a simple balance sheet.
module Hledger.Cli.Commands.Balancesheetequity
balancesheetequitymode :: Mode RawOpts
balancesheetequity :: CliOpts -> Journal -> IO ()

-- | The balancesheet command prints a simple balance sheet.
module Hledger.Cli.Commands.Balancesheet
balancesheetmode :: Mode RawOpts
balancesheet :: CliOpts -> Journal -> IO ()

-- | The aregister command lists a single account's transactions,
--   like the account register in hledger-ui and hledger-web, and unlike
--   the register command which lists postings across multiple accounts.
module Hledger.Cli.Commands.Aregister
aregistermode :: Mode RawOpts

-- | Print an account register report for a specified account.
aregister :: CliOpts -> Journal -> IO ()
tests_Aregister :: TestTree

-- | A history-aware add command to help with data entry. |
module Hledger.Cli.Commands.Add
addmode :: Mode RawOpts

-- | Read multiple transactions from the console, prompting for each field,
--   and append them to the journal file. If the journal came from stdin,
--   this command has no effect.
add :: CliOpts -> Journal -> IO ()

-- | Append a string, typically one or more transactions, to a journal
--   file, or if the file is "-", dump it to stdout. Tries to avoid excess
--   whitespace.
--   
--   XXX This writes unix line endings (n), some at least, even if the file
--   uses dos line endings (rn), which could leave mixed line endings in
--   the file. See also writeFileWithBackupIfChanged.
appendToJournalFileOrStdout :: FilePath -> Text -> IO ()

-- | Append this transaction to the journal's file and transaction list.
journalAddTransaction :: Journal -> CliOpts -> Transaction -> IO Journal
instance GHC.Show.Show Hledger.Cli.Commands.Add.EntryState
instance GHC.Show.Show Hledger.Cli.Commands.Add.RestartTransactionException
instance GHC.Show.Show Hledger.Cli.Commands.Add.TxnParams
instance GHC.Show.Show Hledger.Cli.Commands.Add.PrevInput
instance GHC.Exception.Type.Exception Hledger.Cli.Commands.Add.RestartTransactionException

module Hledger.Cli.Commands.Import
importmode :: Mode RawOpts
importcmd :: CliOpts -> Journal -> IO ()

-- | Print a bar chart of posting activity per day, or other report
--   interval.
module Hledger.Cli.Commands.Activity
activitymode :: Mode RawOpts
barchar :: Char

-- | Print a bar chart of number of postings per report interval.
activity :: CliOpts -> Journal -> IO ()
showHistogram :: ReportSpec -> Journal -> String
printDayWith :: (PrintfArg t, PrintfType t) => (t -> t) -> (DateSpan, t) -> t
countBar :: Foldable t => t a -> [Char]

-- | The accounts command lists account names:
--   
--   
--   
- in flat mode (default), it lists the full names of accounts posted
--   to by matched postings, clipped to the specified depth, possibly with
--   leading components dropped.
--   
- in tree mode, it shows the indented short names of accounts posted
--   to by matched postings, and their parents, to the specified
--   depth.
--   
module Hledger.Cli.Commands.Accounts

-- | Command line options for this command.
accountsmode :: Mode RawOpts

-- | The accounts command.
accounts :: CliOpts -> Journal -> IO ()

-- | hledger's built-in commands, and helpers for printing the commands
--   list.
--   
--   New built-in commands should be added in four places below: the export
--   list, the import list, builtinCommands, commandsList.
module Hledger.Cli.Commands

-- | The test command, which runs the hledger and hledger-lib packages'
--   unit tests. This command also accepts tasty test runner options,
--   written after a -- (double hyphen).
--   
--   Unlike most hledger commands, this one does not read the user's
--   journal. A Journal argument remains in the type signature, but
--   it should not be used (and would raise an error).
testcmd :: CliOpts -> Journal -> IO ()

-- | The cmdargs subcommand mode (for command-line parsing) and IO action
--   (for doing the command's work) for each builtin command. Command
--   actions take parsed CLI options and a (lazy) finalised journal.
builtinCommands :: [(Mode RawOpts, CliOpts -> Journal -> IO ())]

-- | All names and aliases of the builtin commands.
builtinCommandNames :: [String]

-- | Look up a builtin command's mode and action by exact command name or
--   alias.
findBuiltinCommand :: String -> Maybe (Mode RawOpts, CliOpts -> Journal -> IO ())

-- | Canonical names of the known addon commands which have a slot in the
--   commands list, in alphabetical order.
knownAddonCommands :: [String]

-- | Canonical names of all commands which have a slot in the commands
--   list, in alphabetical order. These include the builtin commands and
--   the known addon commands.
knownCommands :: [String]

-- | Print the commands list, with a pager if appropriate, customising the
--   commandsList template above with the given version string and the
--   installed addons. Uninstalled known addons will be removed from the
--   list, installed known addons will have the + prefix removed, and
--   installed unknown addons will be added under Misc.
printCommandsList :: String -> [String] -> IO ()
tests_Hledger_Cli :: TestTree

-- | This is the root module of the hledger package, providing
--   hledger's command-line interface. The main function, commands,
--   command-line options, and utilities useful to other hledger
--   command-line programs are exported. It also re-exports
--   hledger-lib:Hledger and cmdargs:System.Concole.CmdArgs.Explicit
--   
--   See also:
--   
--   
--   
- hledger-lib:Hledger
--   
- The README files
--   
- The high-level developer docs
--   
--   
--   
About
--   
--   hledger - a fast, reliable, user-friendly plain text accounting tool.
--   Copyright (c) 2007-2023 Simon Michael simon@joyful.com and
--   contributors Released under GPL version 3 or later.
--   
--   hledger is a Haskell rewrite of John Wiegley's "ledger". It generates
--   financial reports from a plain text general journal. You can use the
--   command line:
--   
--   
--   $ hledger
--   
--   
--   or ghci:
--   
--   
--   $ make ghci
--   ghci> Right j <- runExceptT $ readJournalFile definputopts "examples/sample.journal"  -- or: j <- defaultJournal
--   ghci> :t j
--   j :: Journal
--   ghci> stats defcliopts j
--   Main file                : examples/sample.journal
--   Included files           : 
--   Transactions span        : 2008-01-01 to 2009-01-01 (366 days)
--   Last transaction         : 2008-12-31 (733772 days from now)
--   Transactions             : 5 (0.0 per day)
--   Transactions last 30 days: 0 (0.0 per day)
--   Transactions last 7 days : 0 (0.0 per day)
--   Payees/descriptions      : 5
--   Accounts                 : 8 (depth 3)
--   Commodities              : 1 ($)
--   Market prices            : 0 ()
--   
--   Run time (throughput)    : 1695276900.00s (0 txns/s)
--   ghci> balance defcliopts j
--                     $1  assets:bank:saving
--                    $-2  assets:cash
--                     $1  expenses:food
--                     $1  expenses:supplies
--                    $-1  income:gifts
--                    $-1  income:salary
--                     $1  liabilities:debts
--   --------------------
--                      0  
--   ghci> 
--   
--   
--   etc.
module Hledger.Cli

-- | The program name and version string for this build of the hledger
--   tool, including any git info available at build time.
prognameandversion :: String

-- | A helper to generate the best version string we can from the given
--   program name and package version strings, current os and architecture,
--   and any git info available at build time (commit hash, commit date,
--   branch name, patchlevel since latest release tag for that program's
--   package). Typically called for programs "hledger", "hledger-ui", or
--   "hledger-web".
--   
--   The git info changes whenever any file in the repository changes.
--   Keeping this template haskell call here and not down in
--   Hledger.Cli.Version helps reduce the number of modules recompiled.
versionString :: ProgramName -> PackageVersion -> String

-- | Let's go!
main :: IO ()

-- | The overall cmdargs mode describing hledger's command-line options and
--   subcommands.
mainmode :: [Name] -> Mode RawOpts

-- | Parse hledger CLI options from these command line arguments and add-on
--   command names, or raise any error.
argsToCliOpts :: [String] -> [String] -> IO CliOpts

-- | An unnamed argument. Anything not starting with - is
--   considered an argument, apart from "-" which is considered to
--   be the argument "-", and any arguments following
--   "--". For example:
--   
--   
--   programname arg1 -j - --foo arg3 -- -arg4 --arg5=1 arg6
--   
--   
--   Would have the arguments:
--   
--   
--   ["arg1","-","arg3","-arg4","--arg5=1","arg6"]
--   
data () => Arg a
Arg :: Update a -> FlagHelp -> Bool -> Arg a

-- | A way of processing the argument.
[argValue] :: Arg a -> Update a

-- | The type of data for the argument, i.e. FILE/DIR/EXT
[argType] :: Arg a -> FlagHelp

-- | Is at least one of these arguments required, the command line will
--   fail if none are set
[argRequire] :: Arg a -> Bool

-- | Like functor, but where the the argument isn't just covariant.
class () => Remap (m :: Type -> Type)

-- | Convert between two values.
remap :: Remap m => (a -> b) -> (b -> (a, a -> b)) -> m a -> m b

-- | A flag, consisting of a list of flag names and other information.
data () => Flag a
Flag :: [Name] -> FlagInfo -> Update a -> FlagHelp -> Help -> Flag a

-- | The names for the flag.
[flagNames] :: Flag a -> [Name]

-- | Information about a flag's arguments.
[flagInfo] :: Flag a -> FlagInfo

-- | The way of processing a flag.
[flagValue] :: Flag a -> Update a

-- | The type of data for the flag argument, i.e. FILE/DIR/EXT
[flagType] :: Flag a -> FlagHelp

-- | The help message associated with this flag.
[flagHelp] :: Flag a -> Help

-- | A function to take a string, and a value, and either produce an error
--   message (Left), or a modified value (Right).
type Update a = String -> a -> Either String a

-- | The FlagInfo type has the following meaning:
--   
--   
--                FlagReq     FlagOpt      FlagOptRare/FlagNone
--   -xfoo        -x=foo      -x=foo       -x -foo
--   -x foo       -x=foo      -x foo       -x foo
--   -x=foo       -x=foo      -x=foo       -x=foo
--   --xx foo     --xx=foo    --xx foo     --xx foo
--   --xx=foo     --xx=foo    --xx=foo     --xx=foo
--   
data () => FlagInfo

-- | Required argument
FlagReq :: FlagInfo

-- | Optional argument
FlagOpt :: String -> FlagInfo

-- | Optional argument that requires an = before the value
FlagOptRare :: String -> FlagInfo

-- | No argument
FlagNone :: FlagInfo

-- | A mode. Do not use the Mode constructor directly, instead use
--   mode to construct the Mode and then record updates. Each
--   mode has three main features:
--   
--   
--   
- A list of submodes (modeGroupModes)
--   
- A list of flags (modeGroupFlags)
--   
- Optionally an unnamed argument (modeArgs)
--   
--   
--   To produce the help information for a mode, either use
--   helpText or show.
data () => Mode a
Mode :: Group (Mode a) -> [Name] -> a -> (a -> Either String a) -> (a -> Maybe [String]) -> Bool -> Help -> [String] -> ([Arg a], Maybe (Arg a)) -> Group (Flag a) -> Mode a

-- | The available sub-modes
[modeGroupModes] :: Mode a -> Group (Mode a)

-- | The names assigned to this mode (for the root mode, this name is used
--   as the program name)
[modeNames] :: Mode a -> [Name]

-- | Value to start with
[modeValue] :: Mode a -> a

-- | Check the value reprsented by a mode is correct, after applying all
--   flags
[modeCheck] :: Mode a -> a -> Either String a

-- | Given a value, try to generate the input arguments.
[modeReform] :: Mode a -> a -> Maybe [String]

-- | Expand @ arguments with expandArgsAt, defaults to
--   True, only applied if using an IO processing function.
--   Only the root Modes value will be used.
[modeExpandAt] :: Mode a -> Bool

-- | Help text
[modeHelp] :: Mode a -> Help

-- | A longer help suffix displayed after a mode
[modeHelpSuffix] :: Mode a -> [String]

-- | The unnamed arguments, a series of arguments, followed optionally by
--   one for all remaining slots
[modeArgs] :: Mode a -> ([Arg a], Maybe (Arg a))

-- | Groups of flags
[modeGroupFlags] :: Mode a -> Group (Flag a)

-- | A group of items (modes or flags). The items are treated as a list,
--   but the group structure is used when displaying the help message.
data () => Group a
Group :: [a] -> [a] -> [(Help, [a])] -> Group a

-- | Normal items.
[groupUnnamed] :: Group a -> [a]

-- | Items that are hidden (not displayed in the help message).
[groupHidden] :: Group a -> [a]

-- | Items that have been grouped, along with a description of each group.
[groupNamed] :: Group a -> [(Help, [a])]

-- | The type of a flag, i.e. --foo=TYPE.
type FlagHelp = String

-- | A help message that goes with either a flag or a mode.
type Help = String

-- | How to complete a command line option. The Show instance is
--   suitable for parsing from shell scripts.
data () => Complete

-- | Complete to a particular value
CompleteValue :: String -> Complete

-- | Complete to a prefix, and a file
CompleteFile :: String -> FilePath -> Complete

-- | Complete to a prefix, and a directory
CompleteDir :: String -> FilePath -> Complete

-- | Specify the format to output the help.
data () => HelpFormat

-- | Equivalent to HelpFormatAll if there is not too much text,
--   otherwise HelpFormatOne.
HelpFormatDefault :: HelpFormat

-- | Display only the first mode.
HelpFormatOne :: HelpFormat

-- | Display all modes.
HelpFormatAll :: HelpFormat

-- | Bash completion information
HelpFormatBash :: HelpFormat

-- | Z shell completion information
HelpFormatZsh :: HelpFormat

-- | Process a list of flags (usually obtained from
--   getArgs/expandArgsAt) with a mode. Returns
--   Left and an error message if the command line fails to parse,
--   or Right and the associated value.
process :: Mode a -> [String] -> Either String a

-- | Expand @ directives in a list of arguments, usually obtained
--   from getArgs. As an example, given the file test.txt
--   with the lines hello and world:
--   
--   
--   expandArgsAt ["@test.txt","!"] == ["hello","world","!"]
--   
--   
--   Any @ directives in the files will be recursively expanded
--   (raising an error if there is infinite recursion).
--   
--   To supress @ expansion, pass any @ arguments after
--   --.
expandArgsAt :: [String] -> IO [String]

-- | Given a sequence of arguments, join them together in a manner that
--   could be used on the command line, giving preference to the Windows
--   cmd shell quoting conventions.
--   
--   For an alternative version, intended for actual running the result in
--   a shell, see "System.Process.showCommandForUser"
joinArgs :: [String] -> String

-- | Given a string, split into the available arguments. The inverse of
--   joinArgs.
splitArgs :: String -> [String]

-- | Parse a boolean, accepts as True: true yes on enabled 1.
parseBool :: String -> Maybe Bool

-- | Convert a group into a list.
fromGroup :: Group a -> [a]

-- | Convert a list into a group, placing all fields in
--   groupUnnamed.
toGroup :: [a] -> Group a

-- | Extract the modes from a Mode
modeModes :: Mode a -> [Mode a]

-- | Extract the flags from a Mode
modeFlags :: Mode a -> [Flag a]

-- | Extract the value from inside a FlagOpt or FlagOptRare,
--   or raises an error.
fromFlagOpt :: FlagInfo -> String

-- | Check that a mode is well formed.
checkMode :: Mode a -> Maybe String

-- | Restricted version of remap where the values are isomorphic.
remap2 :: Remap m => (a -> b) -> (b -> a) -> m a -> m b

-- | Version of remap for the Update type alias.
remapUpdate :: (a -> b) -> (b -> (a, a -> b)) -> Update a -> Update b

-- | Create an empty mode specifying only modeValue. All other
--   fields will usually be populated using record updates.
modeEmpty :: a -> Mode a

-- | Create a mode with a name, an initial value, some help text, a way of
--   processing arguments and a list of flags.
mode :: Name -> a -> Help -> Arg a -> [Flag a] -> Mode a

-- | Create a list of modes, with a program name, an initial value, some
--   help text and the child modes.
modes :: String -> a -> Help -> [Mode a] -> Mode a

-- | Create a flag taking no argument value, with a list of flag names, an
--   update function and some help text.
flagNone :: [Name] -> (a -> a) -> Help -> Flag a

-- | Create a flag taking an optional argument value, with an optional
--   value, a list of flag names, an update function, the type of the
--   argument and some help text.
flagOpt :: String -> [Name] -> Update a -> FlagHelp -> Help -> Flag a

-- | Create a flag taking a required argument value, with a list of flag
--   names, an update function, the type of the argument and some help
--   text.
flagReq :: [Name] -> Update a -> FlagHelp -> Help -> Flag a

-- | Create an argument flag, with an update function and the type of the
--   argument.
flagArg :: Update a -> FlagHelp -> Arg a

-- | Create a boolean flag, with a list of flag names, an update function
--   and some help text.
flagBool :: [Name] -> (Bool -> a -> a) -> Help -> Flag a

-- | Given a current state, return the set of commands you could type now,
--   in preference order.
complete :: Mode a -> [String] -> (Int, Int) -> [Complete]

-- | Generate a help message from a mode. The first argument is a prefix,
--   which is prepended when not using HelpFormatBash or
--   HelpFormatZsh.
helpText :: [String] -> HelpFormat -> Mode a -> [Text]

-- | Process the flags obtained by getArgs and
--   expandArgsAt with a mode. Displays an error and exits
--   with failure if the command line fails to parse, or returns the
--   associated value. Implemented in terms of process. This
--   function makes use of the following environment variables:
--   
--   
--   
- $CMDARGS_COMPLETE - causes the program to produce
--   completions using complete, then exit. Completions are based on
--   the result of getArgs, the index of the current argument is
--   taken from $CMDARGS_COMPLETE (set it to - to
--   complete the last argument), and the index within that argument is
--   taken from $CMDARGS_COMPLETE_POS (if set).
--   
- $CMDARGS_HELPER/$CMDARGS_HELPER_PROG -
--   uses the helper mechanism for entering command line programs as
--   described in System.Console.CmdArgs.Helper.
--   
processArgs :: Mode a -> IO a

-- | Process a list of flags (usually obtained from getArgs
--   and expandArgsAt) with a mode. Throws an error if the
--   command line fails to parse, or returns the associated value.
--   Implemeneted in terms of process. This function does not take
--   account of any environment variables that may be set (see
--   processArgs).
--   
--   If you are in IO you will probably get a better user experience
--   by calling processValueIO.
processValue :: Mode a -> [String] -> a

-- | Like processValue but on failure prints to stderr and exits the
--   program.
processValueIO :: Mode a -> [String] -> IO a

-- | Create a help flag triggered by -?/--help.
flagHelpSimple :: (a -> a) -> Flag a

-- | Create a help flag triggered by -?/--help. The user
--   may optionally modify help by specifying the format, such as:
--   
--   
--   --help=all          - help for all modes
--   --help=html         - help in HTML format
--   --help=100          - wrap the text at 100 characters
--   --help=100,one      - full text wrapped at 100 characters
--   
flagHelpFormat :: (HelpFormat -> TextFormat -> a -> a) -> Flag a

-- | Create a version flag triggered by -V/--version.
flagVersion :: (a -> a) -> Flag a

-- | Create a version flag triggered by --numeric-version.
flagNumericVersion :: (a -> a) -> Flag a

-- | Create verbosity flags triggered by -v/--verbose and
--   -q/--quiet
flagsVerbosity :: (Verbosity -> a -> a) -> [Flag a]

-- | A convenient module to import in hledger scripts, aiming to provide
--   the most useful imports and reduce boilerplate. |
module Hledger.Cli.Script

-- | The character type Char is an enumeration whose values
--   represent Unicode (or equivalently ISO/IEC 10646) code points (i.e.
--   characters, see http://www.unicode.org/ for details). This set
--   extends the ISO 8859-1 (Latin-1) character set (the first 256
--   characters), which is itself an extension of the ASCII character set
--   (the first 128 characters). A character literal in Haskell has type
--   Char.
--   
--   To convert a Char to or from the corresponding Int value
--   defined by Unicode, use toEnum and fromEnum from the
--   Enum class respectively (or equivalently ord and
--   chr).
data () => Char
data () => Ordering
LT :: Ordering
EQ :: Ordering
GT :: Ordering

-- | The Maybe type encapsulates an optional value. A value of type
--   Maybe a either contains a value of type a
--   (represented as Just a), or it is empty (represented
--   as Nothing). Using Maybe is a good way to deal with
--   errors or exceptional cases without resorting to drastic measures such
--   as error.
--   
--   The Maybe type is also a monad. It is a simple kind of error
--   monad, where all errors are represented by Nothing. A richer
--   error monad can be built using the Either type.
data () => Maybe a
Nothing :: Maybe a
Just :: a -> Maybe a
type Change = MixedAmount

-- | The Ord class is used for totally ordered datatypes.
--   
--   Instances of Ord can be derived for any user-defined datatype
--   whose constituent types are in Ord. The declared order of the
--   constructors in the data declaration determines the ordering in
--   derived Ord instances. The Ordering datatype allows a
--   single comparison to determine the precise ordering of two objects.
--   
--   Ord, as defined by the Haskell report, implements a total order
--   and has the following properties:
--   
--   
--   
- Comparability x <= y || y <= x =
--   True
--   
- Transitivity if x <= y && y <=
--   z = True, then x <= z = True
--   
- Reflexivity x <= x = True
--   
- Antisymmetry if x <= y && y <=
--   x = True, then x == y = True
--   
--   
--   The following operator interactions are expected to hold:
--   
--   
--   
- x >= y = y <= x
--   
- x < y = x <= y && x /= y
--   
- x > y = y < x
--   
- x < y = compare x y == LT
--   
- x > y = compare x y == GT
--   
- x == y = compare x y == EQ
--   
- min x y == if x <= y then x else y = True
--   
- max x y == if x >= y then x else y = True
--   
--   
--   Note that (7.) and (8.) do not require min and
--   max to return either of their arguments. The result is merely
--   required to equal one of the arguments in terms of (==).
--   
--   Minimal complete definition: either compare or <=.
--   Using compare can be more efficient for complex types.
class Eq a => Ord a
compare :: Ord a => a -> a -> Ordering
(<) :: Ord a => a -> a -> Bool
(<=) :: Ord a => a -> a -> Bool
(>) :: Ord a => a -> a -> Bool
(>=) :: Ord a => a -> a -> Bool
max :: Ord a => a -> a -> a
min :: Ord a => a -> a -> a
infix 4 >=
infix 4 <
infix 4 <=
infix 4 >

-- | A space efficient, packed, unboxed Unicode text type.
data () => Text

-- | This is the simplest representation of UTC. It consists of the day
--   number, and a time offset from midnight. Note that if a day has a leap
--   second added to it, it will have 86401 seconds.
data () => UTCTime
UTCTime :: Day -> DiffTime -> UTCTime

-- | the day
[utctDay] :: UTCTime -> Day

-- | the time from midnight, 0 <= t < 86401s (because of
--   leap-seconds)
[utctDayTime] :: UTCTime -> DiffTime

-- | The Either type represents values with two possibilities: a
--   value of type Either a b is either Left
--   a or Right b.
--   
--   The Either type is sometimes used to represent a value which is
--   either correct or an error; by convention, the Left constructor
--   is used to hold an error value and the Right constructor is
--   used to hold a correct value (mnemonic: "right" also means "correct").
--   
--   
Examples
--   
--   The type Either String Int is the type
--   of values which can be either a String or an Int. The
--   Left constructor can be used only on Strings, and the
--   Right constructor can be used only on Ints:
--   
--   
--   >>> let s = Left "foo" :: Either String Int
--   
--   >>> s
--   Left "foo"
--   
--   >>> let n = Right 3 :: Either String Int
--   
--   >>> n
--   Right 3
--   
--   >>> :type s
--   s :: Either String Int
--   
--   >>> :type n
--   n :: Either String Int
--   
--   
--   The fmap from our Functor instance will ignore
--   Left values, but will apply the supplied function to values
--   contained in a Right:
--   
--   
--   >>> let s = Left "foo" :: Either String Int
--   
--   >>> let n = Right 3 :: Either String Int
--   
--   >>> fmap (*2) s
--   Left "foo"
--   
--   >>> fmap (*2) n
--   Right 6
--   
--   
--   The Monad instance for Either allows us to chain
--   together multiple actions which may fail, and fail overall if any of
--   the individual steps failed. First we'll write a function that can
--   either parse an Int from a Char, or fail.
--   
--   
--   >>> import Data.Char ( digitToInt, isDigit )
--   
--   >>> :{
--       let parseEither :: Char -> Either String Int
--           parseEither c
--             | isDigit c = Right (digitToInt c)
--             | otherwise = Left "parse error"
--   
--   >>> :}
--   
--   
--   The following should work, since both '1' and '2'
--   can be parsed as Ints.
--   
--   
--   >>> :{
--       let parseMultiple :: Either String Int
--           parseMultiple = do
--             x <- parseEither '1'
--             y <- parseEither '2'
--             return (x + y)
--   
--   >>> :}
--   
--   
--   
--   >>> parseMultiple
--   Right 3
--   
--   
--   But the following should fail overall, since the first operation where
--   we attempt to parse 'm' as an Int will fail:
--   
--   
--   >>> :{
--       let parseMultiple :: Either String Int
--           parseMultiple = do
--             x <- parseEither 'm'
--             y <- parseEither '2'
--             return (x + y)
--   
--   >>> :}
--   
--   
--   
--   >>> parseMultiple
--   Left "parse error"
--   
data () => Either a b
Left :: a -> Either a b
Right :: b -> Either a b

-- | Year of Common Era (when positive).
type Year = Integer

-- | A name, either the name of a flag (--foo) or the name
--   of a mode.
type Name = String

-- | A value of type IO a is a computation which, when
--   performed, does some I/O before returning a value of type a.
--   
--   There is really only one way to "perform" an I/O action: bind it to
--   Main.main in your program. When your program is run, the I/O
--   will be performed. It isn't possible to perform I/O from an arbitrary
--   function, unless that function is itself in the IO monad and
--   called at some point, directly or indirectly, from Main.main.
--   
--   IO is a monad, so IO actions can be combined using
--   either the do-notation or the >> and >>=
--   operations from the Monad class.
data () => IO a

-- | A functor with application, providing operations to
--   
--   
--   
- embed pure expressions (pure), and
--   
- sequence computations and combine their results (<*>
--   and liftA2).
--   
--   
--   A minimal complete definition must include implementations of
--   pure and of either <*> or liftA2. If it
--   defines both, then they must behave the same as their default
--   definitions:
--   
--   
--   (<*>) = liftA2 id
--   
--   
--   
--   liftA2 f x y = f <$> x <*> y
--   
--   
--   Further, any definition must satisfy the following:
--   
--   
--   
- Identity 
pure id <*> v =
--   v

--   
- Composition 
pure (.) <*> u
--   <*> v <*> w = u <*> (v
--   <*> w)

--   
- Homomorphism 
pure f <*>
--   pure x = pure (f x)

--   
- Interchange 
u <*> pure y =
--   pure ($ y) <*> u

--   
--   
--   The other methods have the following default definitions, which may be
--   overridden with equivalent specialized implementations:
--   
--   
--   
- 
u *> v = (id <$ u)
--   <*> v

--   
- 
u <* v = liftA2 const u v

--   
--   
--   As a consequence of these laws, the Functor instance for
--   f will satisfy
--   
--   
--   
- 
fmap f x = pure f <*> x

--   
--   
--   It may be useful to note that supposing
--   
--   
--   forall x y. p (q x y) = f x . g y
--   
--   
--   it follows from the above that
--   
--   
--   liftA2 p (liftA2 q u v) = liftA2 f u . liftA2 g v
--   
--   
--   If f is also a Monad, it should satisfy
--   
--   
--   
- 
pure = return

--   
- 
m1 <*> m2 = m1 >>= (\x1 -> m2
--   >>= (\x2 -> return (x1 x2)))

--   
- 
(*>) = (>>)

--   
--   
--   (which implies that pure and <*> satisfy the
--   applicative functor laws).
class Functor f => Applicative (f :: Type -> Type)

-- | Lift a value.
pure :: Applicative f => a -> f a

-- | Sequential application.
--   
--   A few functors support an implementation of <*> that is
--   more efficient than the default one.
--   
--   
Example
--   
--   Used in combination with (<$>),
--   (<*>) can be used to build a record.
--   
--   
--   >>> data MyState = MyState {arg1 :: Foo, arg2 :: Bar, arg3 :: Baz}
--   
--   
--   
--   >>> produceFoo :: Applicative f => f Foo
--   
--   
--   
--   >>> produceBar :: Applicative f => f Bar
--   
--   >>> produceBaz :: Applicative f => f Baz
--   
--   
--   
--   >>> mkState :: Applicative f => f MyState
--   
--   >>> mkState = MyState <$> produceFoo <*> produceBar <*> produceBaz
--   
(<*>) :: Applicative f => f (a -> b) -> f a -> f b

-- | Lift a binary function to actions.
--   
--   Some functors support an implementation of liftA2 that is more
--   efficient than the default one. In particular, if fmap is an
--   expensive operation, it is likely better to use liftA2 than to
--   fmap over the structure and then use <*>.
--   
--   This became a typeclass method in 4.10.0.0. Prior to that, it was a
--   function defined in terms of <*> and fmap.
--   
--   
Example
--   
--   
--   >>> liftA2 (,) (Just 3) (Just 5)
--   Just (3,5)
--   
liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c

-- | Sequence actions, discarding the value of the first argument.
--   
--   
Examples
--   
--   If used in conjunction with the Applicative instance for Maybe,
--   you can chain Maybe computations, with a possible "early return" in
--   case of Nothing.
--   
--   
--   >>> Just 2 *> Just 3
--   Just 3
--   
--   
--   
--   >>> Nothing *> Just 3
--   Nothing
--   
--   
--   Of course a more interesting use case would be to have effectful
--   computations instead of just returning pure values.
--   
--   
--   >>> import Data.Char
--   
--   >>> import Text.ParserCombinators.ReadP
--   
--   >>> let p = string "my name is " *> munch1 isAlpha <* eof
--   
--   >>> readP_to_S p "my name is Simon"
--   [("Simon","")]
--   
(*>) :: Applicative f => f a -> f b -> f b

-- | Sequence actions, discarding the value of the second argument.
(<*) :: Applicative f => f a -> f b -> f a
infixl 4 <*>
infixl 4 *>
infixl 4 <*

-- | A type f is a Functor if it provides a function fmap
--   which, given any types a and b lets you apply any
--   function from (a -> b) to turn an f a into an
--   f b, preserving the structure of f. Furthermore
--   f needs to adhere to the following:
--   
--   
--   
- Identity fmap id == id
--   
- Composition fmap (f . g) == fmap f .
--   fmap g
--   
--   
--   Note, that the second law follows from the free theorem of the type
--   fmap and the first law, so you need only check that the former
--   condition holds. See
--   https://www.schoolofhaskell.com/user/edwardk/snippets/fmap or
--   https://github.com/quchen/articles/blob/master/second_functor_law.md
--   for an explanation.
class () => Functor (f :: Type -> Type)

-- | fmap is used to apply a function of type (a -> b)
--   to a value of type f a, where f is a functor, to produce a
--   value of type f b. Note that for any type constructor with
--   more than one parameter (e.g., Either), only the last type
--   parameter can be modified with fmap (e.g., b in
--   `Either a b`).
--   
--   Some type constructors with two parameters or more have a
--   Bifunctor instance that allows both the last and the
--   penultimate parameters to be mapped over.
--   
--   
Examples
--   
--   Convert from a Maybe Int to a Maybe String
--   using show:
--   
--   
--   >>> fmap show Nothing
--   Nothing
--   
--   >>> fmap show (Just 3)
--   Just "3"
--   
--   
--   Convert from an Either Int Int to an Either Int
--   String using show:
--   
--   
--   >>> fmap show (Left 17)
--   Left 17
--   
--   >>> fmap show (Right 17)
--   Right "17"
--   
--   
--   Double each element of a list:
--   
--   
--   >>> fmap (*2) [1,2,3]
--   [2,4,6]
--   
--   
--   Apply even to the second element of a pair:
--   
--   
--   >>> fmap even (2,2)
--   (2,True)
--   
--   
--   It may seem surprising that the function is only applied to the last
--   element of the tuple compared to the list example above which applies
--   it to every element in the list. To understand, remember that tuples
--   are type constructors with multiple type parameters: a tuple of 3
--   elements (a,b,c) can also be written (,,) a b c and
--   its Functor instance is defined for Functor ((,,) a
--   b) (i.e., only the third parameter is free to be mapped over with
--   fmap).
--   
--   It explains why fmap can be used with tuples containing
--   values of different types as in the following example:
--   
--   
--   >>> fmap even ("hello", 1.0, 4)
--   ("hello",1.0,True)
--   
fmap :: Functor f => (a -> b) -> f a -> f b

-- | Replace all locations in the input with the same value. The default
--   definition is fmap . const, but this may be
--   overridden with a more efficient version.
--   
--   
Examples
--   
--   Perform a computation with Maybe and replace the result with a
--   constant value if it is Just:
--   
--   
--   >>> 'a' <$ Just 2
--   Just 'a'
--   
--   >>> 'a' <$ Nothing
--   Nothing
--   
(<$) :: Functor f => a -> f b -> f a
infixl 4 <$

-- | The Monad class defines the basic operations over a
--   monad, a concept from a branch of mathematics known as
--   category theory. From the perspective of a Haskell programmer,
--   however, it is best to think of a monad as an abstract datatype
--   of actions. Haskell's do expressions provide a convenient
--   syntax for writing monadic expressions.
--   
--   Instances of Monad should satisfy the following:
--   
--   
--   
- Left identity return a >>= k = k
--   a
--   
- Right identity m >>= return =
--   m
--   
- Associativity m >>= (\x -> k x
--   >>= h) = (m >>= k) >>=
--   h
--   
--   
--   Furthermore, the Monad and Applicative operations should
--   relate as follows:
--   
--   
--   
- 
pure = return

--   
- 
m1 <*> m2 = m1 >>= (\x1 -> m2
--   >>= (\x2 -> return (x1 x2)))

--   
--   
--   The above laws imply:
--   
--   
--   
- 
fmap f xs = xs >>= return .
--   f

--   
- 
(>>) = (*>)

--   
--   
--   and that pure and (<*>) satisfy the applicative
--   functor laws.
--   
--   The instances of Monad for lists, Maybe and IO
--   defined in the Prelude satisfy these laws.
class Applicative m => Monad (m :: Type -> Type)

-- | Sequentially compose two actions, passing any value produced by the
--   first as an argument to the second.
--   
--   'as >>= bs' can be understood as the do
--   expression
--   
--   
--   do a <- as
--      bs a
--   
(>>=) :: Monad m => m a -> (a -> m b) -> m b

-- | Sequentially compose two actions, discarding any value produced by the
--   first, like sequencing operators (such as the semicolon) in imperative
--   languages.
--   
--   'as >> bs' can be understood as the do
--   expression
--   
--   
--   do as
--      bs
--   
(>>) :: Monad m => m a -> m b -> m b

-- | Inject a value into the monadic type.
return :: Monad m => a -> m a
infixl 1 >>=
infixl 1 >>

-- | When a value is bound in do-notation, the pattern on the left
--   hand side of <- might not match. In this case, this class
--   provides a function to recover.
--   
--   A Monad without a MonadFail instance may only be used in
--   conjunction with pattern that always match, such as newtypes, tuples,
--   data types with only a single data constructor, and irrefutable
--   patterns (~pat).
--   
--   Instances of MonadFail should satisfy the following law:
--   fail s should be a left zero for >>=,
--   
--   
--   fail s >>= f  =  fail s
--   
--   
--   If your Monad is also MonadPlus, a popular definition is
--   
--   
--   fail _ = mzero
--   
--   
--   fail s should be an action that runs in the monad itself, not
--   an exception (except in instances of MonadIO). In particular,
--   fail should not be implemented in terms of error.
class Monad m => MonadFail (m :: Type -> Type)
fail :: MonadFail m => String -> m a

-- | Haskell defines operations to read and write characters from and to
--   files, represented by values of type Handle. Each value of
--   this type is a handle: a record used by the Haskell run-time
--   system to manage I/O with file system objects. A handle has at
--   least the following properties:
--   
--   
--   
- whether it manages input or output or both;
--   
- whether it is open, closed or
--   semi-closed;
--   
- whether the object is seekable;
--   
- whether buffering is disabled, or enabled on a line or block
--   basis;
--   
- a buffer (whose length may be zero).
--   
--   
--   Most handles will also have a current I/O position indicating where
--   the next input or output operation will occur. A handle is
--   readable if it manages only input or both input and output;
--   likewise, it is writable if it manages only output or both
--   input and output. A handle is open when first allocated. Once
--   it is closed it can no longer be used for either input or output,
--   though an implementation cannot re-use its storage while references
--   remain to it. Handles are in the Show and Eq classes.
--   The string produced by showing a handle is system dependent; it should
--   include enough information to identify the handle for debugging. A
--   handle is equal according to == only to itself; no attempt is
--   made to compare the internal state of different handles for equality.
data () => Handle

-- | Monads that also support choice and failure.
class (Alternative m, Monad m) => MonadPlus (m :: Type -> Type)

-- | The identity of mplus. It should also satisfy the equations
--   
--   
--   mzero >>= f  =  mzero
--   v >> mzero   =  mzero
--   
--   
--   The default definition is
--   
--   
--   mzero = empty
--   
mzero :: MonadPlus m => m a

-- | An associative operation. The default definition is
--   
--   
--   mplus = (<|>)
--   
mplus :: MonadPlus m => m a -> m a -> m a

-- | An MVar (pronounced "em-var") is a synchronising variable, used
--   for communication between concurrent threads. It can be thought of as
--   a box, which may be empty or full.
data () => MVar a

-- | A TextEncoding is a specification of a conversion scheme
--   between sequences of bytes and sequences of Unicode characters.
--   
--   For example, UTF-8 is an encoding of Unicode characters into a
--   sequence of bytes. The TextEncoding for UTF-8 is utf8.
data () => TextEncoding

-- | The Haskell 2010 type for exceptions in the IO monad. Any I/O
--   operation may raise an IOException instead of returning a
--   result. For a more general type of exception, including also those
--   that arise in pure code, see Exception.
--   
--   In Haskell 2010, this is an opaque type.
type IOError = IOException

-- | Chan is an abstract type representing an unbounded FIFO
--   channel.
data () => Chan a

-- | Request a CallStack.
--   
--   NOTE: The implicit parameter ?callStack :: CallStack is an
--   implementation detail and should not be considered part of the
--   CallStack API, we may decide to change the implementation in
--   the future.
type HasCallStack = ?callStack :: CallStack

-- | A monoid on applicative functors.
--   
--   If defined, some and many should be the least solutions
--   of the equations:
--   
--   
--   
- 
some v = (:) <$> v <*>
--   many v

--   
- 
many v = some v <|> pure
--   []

--   
class Applicative f => Alternative (f :: Type -> Type)

-- | The identity of <|>
empty :: Alternative f => f a

-- | An associative binary operation
(<|>) :: Alternative f => f a -> f a -> f a

-- | One or more.
some :: Alternative f => f a -> f [a]

-- | Zero or more.
many :: Alternative f => f a -> f [a]
infixl 3 <|>

-- | Unicode General Categories (column 2 of the UnicodeData table) in the
--   order they are listed in the Unicode standard (the Unicode Character
--   Database, in particular).
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> :t OtherLetter
--   OtherLetter :: GeneralCategory
--   
--   
--   Eq instance:
--   
--   
--   >>> UppercaseLetter == UppercaseLetter
--   True
--   
--   >>> UppercaseLetter == LowercaseLetter
--   False
--   
--   
--   Ord instance:
--   
--   
--   >>> NonSpacingMark <= MathSymbol
--   True
--   
--   
--   Enum instance:
--   
--   
--   >>> enumFromTo ModifierLetter SpacingCombiningMark
--   [ModifierLetter,OtherLetter,NonSpacingMark,SpacingCombiningMark]
--   
--   
--   Read instance:
--   
--   
--   >>> read "DashPunctuation" :: GeneralCategory
--   DashPunctuation
--   
--   >>> read "17" :: GeneralCategory
--   *** Exception: Prelude.read: no parse
--   
--   
--   Show instance:
--   
--   
--   >>> show EnclosingMark
--   "EnclosingMark"
--   
--   
--   Bounded instance:
--   
--   
--   >>> minBound :: GeneralCategory
--   UppercaseLetter
--   
--   >>> maxBound :: GeneralCategory
--   NotAssigned
--   
--   
--   Ix instance:
--   
--   
--   >>> import Data.Ix ( index )
--   
--   >>> index (OtherLetter,Control) FinalQuote
--   12
--   
--   >>> index (OtherLetter,Control) Format
--   *** Exception: Error in array index
--   
data () => GeneralCategory

-- | Lu: Letter, Uppercase
UppercaseLetter :: GeneralCategory

-- | Ll: Letter, Lowercase
LowercaseLetter :: GeneralCategory

-- | Lt: Letter, Titlecase
TitlecaseLetter :: GeneralCategory

-- | Lm: Letter, Modifier
ModifierLetter :: GeneralCategory

-- | Lo: Letter, Other
OtherLetter :: GeneralCategory

-- | Mn: Mark, Non-Spacing
NonSpacingMark :: GeneralCategory

-- | Mc: Mark, Spacing Combining
SpacingCombiningMark :: GeneralCategory

-- | Me: Mark, Enclosing
EnclosingMark :: GeneralCategory

-- | Nd: Number, Decimal
DecimalNumber :: GeneralCategory

-- | Nl: Number, Letter
LetterNumber :: GeneralCategory

-- | No: Number, Other
OtherNumber :: GeneralCategory

-- | Pc: Punctuation, Connector
ConnectorPunctuation :: GeneralCategory

-- | Pd: Punctuation, Dash
DashPunctuation :: GeneralCategory

-- | Ps: Punctuation, Open
OpenPunctuation :: GeneralCategory

-- | Pe: Punctuation, Close
ClosePunctuation :: GeneralCategory

-- | Pi: Punctuation, Initial quote
InitialQuote :: GeneralCategory

-- | Pf: Punctuation, Final quote
FinalQuote :: GeneralCategory

-- | Po: Punctuation, Other
OtherPunctuation :: GeneralCategory

-- | Sm: Symbol, Math
MathSymbol :: GeneralCategory

-- | Sc: Symbol, Currency
CurrencySymbol :: GeneralCategory

-- | Sk: Symbol, Modifier
ModifierSymbol :: GeneralCategory

-- | So: Symbol, Other
OtherSymbol :: GeneralCategory

-- | Zs: Separator, Space
Space :: GeneralCategory

-- | Zl: Separator, Line
LineSeparator :: GeneralCategory

-- | Zp: Separator, Paragraph
ParagraphSeparator :: GeneralCategory

-- | Cc: Other, Control
Control :: GeneralCategory

-- | Cf: Other, Format
Format :: GeneralCategory

-- | Cs: Other, Surrogate
Surrogate :: GeneralCategory

-- | Co: Other, Private Use
PrivateUse :: GeneralCategory

-- | Cn: Other, Not Assigned
NotAssigned :: GeneralCategory

-- | A ThreadId is an abstract type representing a handle to a
--   thread. ThreadId is an instance of Eq, Ord and
--   Show, where the Ord instance implements an arbitrary
--   total ordering over ThreadIds. The Show instance lets
--   you convert an arbitrary-valued ThreadId to string form;
--   showing a ThreadId value is occasionally useful when debugging
--   or diagnosing the behaviour of a concurrent program.
--   
--   Note: in GHC, if you have a ThreadId, you essentially
--   have a pointer to the thread itself. This means the thread itself
--   can't be garbage collected until you drop the ThreadId. This
--   misfeature will hopefully be corrected at a later date.
data () => ThreadId

-- | The Down type allows you to reverse sort order conveniently. A
--   value of type Down a contains a value of type
--   a (represented as Down a).
--   
--   If a has an Ord instance associated with it
--   then comparing two values thus wrapped will give you the opposite of
--   their normal sort order. This is particularly useful when sorting in
--   generalised list comprehensions, as in: then sortWith by
--   Down x.
--   
--   
--   >>> compare True False
--   GT
--   
--   
--   
--   >>> compare (Down True) (Down False)
--   LT
--   
--   
--   If a has a Bounded instance then the wrapped
--   instance also respects the reversed ordering by exchanging the values
--   of minBound and maxBound.
--   
--   
--   >>> minBound :: Int
--   -9223372036854775808
--   
--   
--   
--   >>> minBound :: Down Int
--   Down 9223372036854775807
--   
--   
--   All other instances of Down a behave as they do for
--   a.
newtype () => Down a
Down :: a -> Down a

[getDown] :: Down a -> a

-- | See openFile
data () => IOMode
ReadMode :: IOMode
WriteMode :: IOMode
AppendMode :: IOMode
ReadWriteMode :: IOMode

-- | The Const functor.
newtype () => Const a (b :: k)
Const :: a -> Const a (b :: k)
[getConst] :: Const a (b :: k) -> a

-- | File and directory names are values of type String, whose
--   precise meaning is operating system dependent. Files can be opened,
--   yielding a handle which can then be used to operate on the contents of
--   that file.
type FilePath = String

-- | A mode that determines the effect of hSeek hdl mode i.
data () => SeekMode

-- | the position of hdl is set to i.
AbsoluteSeek :: SeekMode

-- | the position of hdl is set to offset i from the
--   current position.
RelativeSeek :: SeekMode

-- | the position of hdl is set to offset i from the end
--   of the file.
SeekFromEnd :: SeekMode

-- | Specifies the translation, if any, of newline characters between
--   internal Strings and the external file or stream. Haskell Strings are
--   assumed to represent newlines with the '\n' character; the
--   newline mode specifies how to translate '\n' on output, and
--   what to translate into '\n' on input.
data () => NewlineMode
NewlineMode :: Newline -> Newline -> NewlineMode

-- | the representation of newlines on input
[inputNL] :: NewlineMode -> Newline

-- | the representation of newlines on output
[outputNL] :: NewlineMode -> Newline

-- | The representation of a newline in the external file or stream.
data () => Newline

-- | 
--   '\n'
--   
LF :: Newline

-- | 
--   '\r\n'
--   
CRLF :: Newline

-- | Three kinds of buffering are supported: line-buffering,
--   block-buffering or no-buffering. These modes have the following
--   effects. For output, items are written out, or flushed, from
--   the internal buffer according to the buffer mode:
--   
--   
--   
- line-buffering: the entire output buffer is flushed
--   whenever a newline is output, the buffer overflows, a hFlush is
--   issued, or the handle is closed.
--   
- block-buffering: the entire buffer is written out whenever
--   it overflows, a hFlush is issued, or the handle is closed.
--   
- no-buffering: output is written immediately, and never
--   stored in the buffer.
--   
--   
--   An implementation is free to flush the buffer more frequently, but not
--   less frequently, than specified above. The output buffer is emptied as
--   soon as it has been written out.
--   
--   Similarly, input occurs according to the buffer mode for the handle:
--   
--   
--   
- line-buffering: when the buffer for the handle is not
--   empty, the next item is obtained from the buffer; otherwise, when the
--   buffer is empty, characters up to and including the next newline
--   character are read into the buffer. No characters are available until
--   the newline character is available or the buffer is full.
--   
- block-buffering: when the buffer for the handle becomes
--   empty, the next block of data is read into the buffer.
--   
- no-buffering: the next input item is read and returned. The
--   hLookAhead operation implies that even a no-buffered handle may
--   require a one-character buffer.
--   
--   
--   The default buffering mode when a handle is opened is
--   implementation-dependent and may depend on the file system object
--   which is attached to that handle. For most implementations, physical
--   files will normally be block-buffered and terminals will normally be
--   line-buffered.
data () => BufferMode

-- | buffering is disabled if possible.
NoBuffering :: BufferMode

-- | line-buffering should be enabled if possible.
LineBuffering :: BufferMode

-- | block-buffering should be enabled if possible. The size of the buffer
--   is n items if the argument is Just n and is
--   otherwise implementation-dependent.
BlockBuffering :: Maybe Int -> BufferMode

-- | An abstract type that contains a value for each variant of
--   IOException.
data () => IOErrorType

-- | Defines the exit codes that a program can return.
data () => ExitCode

-- | indicates successful termination;
ExitSuccess :: ExitCode

-- | indicates program failure with an exit code. The exact interpretation
--   of the code is operating-system dependent. In particular, some values
--   may be prohibited (e.g. 0 on a POSIX-compliant system).
ExitFailure :: Int -> ExitCode
data () => HandlePosn

-- | Lists, but with an Applicative functor based on zipping.
newtype () => ZipList a
ZipList :: [a] -> ZipList a
[getZipList] :: ZipList a -> [a]
newtype () => WrappedArrow (a :: Type -> Type -> Type) b c
WrapArrow :: a b c -> WrappedArrow (a :: Type -> Type -> Type) b c
[unwrapArrow] :: WrappedArrow (a :: Type -> Type -> Type) b c -> a b c
newtype () => WrappedMonad (m :: Type -> Type) a
WrapMonad :: m a -> WrappedMonad (m :: Type -> Type) a
[unwrapMonad] :: WrappedMonad (m :: Type -> Type) a -> m a

-- | Type of a function that will parse modifier characters from the format
--   string.
type ModifierParser = String -> FormatParse

-- | This is the type of a field formatter reified over its argument.
type FieldFormatter = FieldFormat -> ShowS

-- | The "format parser" walks over argument-type-specific modifier
--   characters to find the primary format character. This is the type of
--   its result.
data () => FormatParse
FormatParse :: String -> Char -> String -> FormatParse

-- | Any modifiers found.
[fpModifiers] :: FormatParse -> String

-- | Primary format character.
[fpChar] :: FormatParse -> Char

-- | Rest of the format string.
[fpRest] :: FormatParse -> String

-- | Description of field formatting for formatArg. See UNIX
--   printf(3) for a description of how field formatting works.
data () => FieldFormat
FieldFormat :: Maybe Int -> Maybe Int -> Maybe FormatAdjustment -> Maybe FormatSign -> Bool -> String -> Char -> FieldFormat

-- | Total width of the field.
[fmtWidth] :: FieldFormat -> Maybe Int

-- | Secondary field width specifier.
[fmtPrecision] :: FieldFormat -> Maybe Int

-- | Kind of filling or padding to be done.
[fmtAdjust] :: FieldFormat -> Maybe FormatAdjustment

-- | Whether to insist on a plus sign for positive numbers.
[fmtSign] :: FieldFormat -> Maybe FormatSign

-- | Indicates an "alternate format". See printf(3) for the
--   details, which vary by argument spec.
[fmtAlternate] :: FieldFormat -> Bool

-- | Characters that appeared immediately to the left of fmtChar in
--   the format and were accepted by the type's parseFormat.
--   Normally the empty string.
[fmtModifiers] :: FieldFormat -> String

-- | The format character printf was invoked with. formatArg
--   should fail unless this character matches the type. It is normal to
--   handle many different format characters for a single type.
[fmtChar] :: FieldFormat -> Char

-- | How to handle the sign of a numeric field. These are mutually
--   exclusive, with SignPlus taking precedence.
data () => FormatSign
SignPlus :: FormatSign
SignSpace :: FormatSign

-- | Whether to left-adjust or zero-pad a field. These are mutually
--   exclusive, with LeftAdjust taking precedence.
data () => FormatAdjustment
LeftAdjust :: FormatAdjustment
ZeroPad :: FormatAdjustment

-- | This class, with only the one instance, is used as a workaround for
--   the fact that String, as a concrete type, is not allowable as a
--   typeclass instance. IsChar is exported for
--   backward-compatibility.
class () => IsChar c

toChar :: IsChar c => c -> Char

fromChar :: IsChar c => Char -> c

-- | Typeclass of printf-formattable values. The formatArg
--   method takes a value and a field format descriptor and either fails
--   due to a bad descriptor or produces a ShowS as the result. The
--   default parseFormat expects no modifiers: this is the normal
--   case. Minimal instance: formatArg.
class () => PrintfArg a

formatArg :: PrintfArg a => a -> FieldFormatter

parseFormat :: PrintfArg a => a -> ModifierParser

-- | The HPrintfType class provides the variable argument magic for
--   hPrintf. Its implementation is intentionally not visible from
--   this module.
class () => HPrintfType t

-- | The PrintfType class provides the variable argument magic for
--   printf. Its implementation is intentionally not visible from
--   this module. If you attempt to pass an argument of a type which is not
--   an instance of this class to printf or hPrintf, then the
--   compiler will report it as a missing instance of PrintfArg.
class () => PrintfType t

-- | QSemN is a quantity semaphore in which the resource is acquired
--   and released in units of one. It provides guaranteed FIFO ordering for
--   satisfying blocked waitQSemN calls.
--   
--   The pattern
--   
--   
--   bracket_ (waitQSemN n) (signalQSemN n) (...)
--   
--   
--   is safe; it never loses any of the resource.
data () => QSemN

-- | QSem is a quantity semaphore in which the resource is acquired
--   and released in units of one. It provides guaranteed FIFO ordering for
--   satisfying blocked waitQSem calls.
--   
--   The pattern
--   
--   
--   bracket_ waitQSem signalQSem (...)
--   
--   
--   is safe; it never loses a unit of the resource.
data () => QSem

-- | Timeout to be applied to individual tests
data () => Timeout

-- | String is the original representation of the timeout (such as
--   "0.5m"), so that we can print it back. Integer is the
--   number of microseconds.
Timeout :: Integer -> String -> Timeout
NoTimeout :: Timeout

-- | An unnamed argument. Anything not starting with - is
--   considered an argument, apart from "-" which is considered to
--   be the argument "-", and any arguments following
--   "--". For example:
--   
--   
--   programname arg1 -j - --foo arg3 -- -arg4 --arg5=1 arg6
--   
--   
--   Would have the arguments:
--   
--   
--   ["arg1","-","arg3","-arg4","--arg5=1","arg6"]
--   
data () => Arg a
Arg :: Update a -> FlagHelp -> Bool -> Arg a

-- | A way of processing the argument.
[argValue] :: Arg a -> Update a

-- | The type of data for the argument, i.e. FILE/DIR/EXT
[argType] :: Arg a -> FlagHelp

-- | Is at least one of these arguments required, the command line will
--   fail if none are set
[argRequire] :: Arg a -> Bool

-- | Like functor, but where the the argument isn't just covariant.
class () => Remap (m :: Type -> Type)

-- | Convert between two values.
remap :: Remap m => (a -> b) -> (b -> (a, a -> b)) -> m a -> m b

-- | A flag, consisting of a list of flag names and other information.
data () => Flag a
Flag :: [Name] -> FlagInfo -> Update a -> FlagHelp -> Help -> Flag a

-- | The names for the flag.
[flagNames] :: Flag a -> [Name]

-- | Information about a flag's arguments.
[flagInfo] :: Flag a -> FlagInfo

-- | The way of processing a flag.
[flagValue] :: Flag a -> Update a

-- | The type of data for the flag argument, i.e. FILE/DIR/EXT
[flagType] :: Flag a -> FlagHelp

-- | The help message associated with this flag.
[flagHelp] :: Flag a -> Help

-- | A function to take a string, and a value, and either produce an error
--   message (Left), or a modified value (Right).
type Update a = String -> a -> Either String a

-- | The FlagInfo type has the following meaning:
--   
--   
--                FlagReq     FlagOpt      FlagOptRare/FlagNone
--   -xfoo        -x=foo      -x=foo       -x -foo
--   -x foo       -x=foo      -x foo       -x foo
--   -x=foo       -x=foo      -x=foo       -x=foo
--   --xx foo     --xx=foo    --xx foo     --xx foo
--   --xx=foo     --xx=foo    --xx=foo     --xx=foo
--   
data () => FlagInfo

-- | Required argument
FlagReq :: FlagInfo

-- | Optional argument
FlagOpt :: String -> FlagInfo

-- | Optional argument that requires an = before the value
FlagOptRare :: String -> FlagInfo

-- | No argument
FlagNone :: FlagInfo

-- | A mode. Do not use the Mode constructor directly, instead use
--   mode to construct the Mode and then record updates. Each
--   mode has three main features:
--   
--   
--   
- A list of submodes (modeGroupModes)
--   
- A list of flags (modeGroupFlags)
--   
- Optionally an unnamed argument (modeArgs)
--   
--   
--   To produce the help information for a mode, either use
--   helpText or show.
data () => Mode a
Mode :: Group (Mode a) -> [Name] -> a -> (a -> Either String a) -> (a -> Maybe [String]) -> Bool -> Help -> [String] -> ([Arg a], Maybe (Arg a)) -> Group (Flag a) -> Mode a

-- | The available sub-modes
[modeGroupModes] :: Mode a -> Group (Mode a)

-- | The names assigned to this mode (for the root mode, this name is used
--   as the program name)
[modeNames] :: Mode a -> [Name]

-- | Value to start with
[modeValue] :: Mode a -> a

-- | Check the value reprsented by a mode is correct, after applying all
--   flags
[modeCheck] :: Mode a -> a -> Either String a

-- | Given a value, try to generate the input arguments.
[modeReform] :: Mode a -> a -> Maybe [String]

-- | Expand @ arguments with expandArgsAt, defaults to
--   True, only applied if using an IO processing function.
--   Only the root Modes value will be used.
[modeExpandAt] :: Mode a -> Bool

-- | Help text
[modeHelp] :: Mode a -> Help

-- | A longer help suffix displayed after a mode
[modeHelpSuffix] :: Mode a -> [String]

-- | The unnamed arguments, a series of arguments, followed optionally by
--   one for all remaining slots
[modeArgs] :: Mode a -> ([Arg a], Maybe (Arg a))

-- | Groups of flags
[modeGroupFlags] :: Mode a -> Group (Flag a)

-- | A group of items (modes or flags). The items are treated as a list,
--   but the group structure is used when displaying the help message.
data () => Group a
Group :: [a] -> [a] -> [(Help, [a])] -> Group a

-- | Normal items.
[groupUnnamed] :: Group a -> [a]

-- | Items that are hidden (not displayed in the help message).
[groupHidden] :: Group a -> [a]

-- | Items that have been grouped, along with a description of each group.
[groupNamed] :: Group a -> [(Help, [a])]

-- | The type of a flag, i.e. --foo=TYPE.
type FlagHelp = String

-- | A help message that goes with either a flag or a mode.
type Help = String

-- | How to complete a command line option. The Show instance is
--   suitable for parsing from shell scripts.
data () => Complete

-- | Complete to a particular value
CompleteValue :: String -> Complete

-- | Complete to a prefix, and a file
CompleteFile :: String -> FilePath -> Complete

-- | Complete to a prefix, and a directory
CompleteDir :: String -> FilePath -> Complete

-- | Specify the format to output the help.
data () => HelpFormat

-- | Equivalent to HelpFormatAll if there is not too much text,
--   otherwise HelpFormatOne.
HelpFormatDefault :: HelpFormat

-- | Display only the first mode.
HelpFormatOne :: HelpFormat

-- | Display all modes.
HelpFormatAll :: HelpFormat

-- | Bash completion information
HelpFormatBash :: HelpFormat

-- | Z shell completion information
HelpFormatZsh :: HelpFormat

-- | A hledger journal reader is a triple of storage format name, a
--   detector of that format, and a parser from that format to Journal. The
--   type variable m appears here so that rParserr can hold a journal
--   parser, which depends on it.
data () => Reader (m :: Type -> Type)
Reader :: StorageFormat -> [String] -> (InputOpts -> FilePath -> Text -> ExceptT String IO Journal) -> (MonadIO m => ErroringJournalParser m ParsedJournal) -> Reader (m :: Type -> Type)
[rFormat] :: Reader (m :: Type -> Type) -> StorageFormat
[rExtensions] :: Reader (m :: Type -> Type) -> [String]
[rReadFn] :: Reader (m :: Type -> Type) -> InputOpts -> FilePath -> Text -> ExceptT String IO Journal
[rParser] :: Reader (m :: Type -> Type) -> MonadIO m => ErroringJournalParser m ParsedJournal

-- | Search paths for various application data, as specified by the XDG
--   Base Directory Specification.
--   
--   The list of paths is split using searchPathSeparator, which on
--   Windows is a semicolon.
--   
--   Note: On Windows, XdgDataDirs and XdgConfigDirs usually
--   yield the same result.
data () => XdgDirectoryList

-- | For data files (e.g. images). It uses the XDG_DATA_DIRS
--   environment variable. On non-Windows systems, the default is
--   /usr/local/share/ and /usr/share/. On Windows, the
--   default is %PROGRAMDATA% or %ALLUSERSPROFILE% (e.g.
--   C:/ProgramData).
XdgDataDirs :: XdgDirectoryList

-- | For configuration files. It uses the XDG_CONFIG_DIRS
--   environment variable. On non-Windows systems, the default is
--   /etc/xdg. On Windows, the default is %PROGRAMDATA%
--   or %ALLUSERSPROFILE% (e.g. C:/ProgramData).
XdgConfigDirs :: XdgDirectoryList

-- | Special directories for storing user-specific application data,
--   configuration, and cache files, as specified by the XDG Base
--   Directory Specification.
--   
--   Note: On Windows, XdgData and XdgConfig usually map to
--   the same directory.
data () => XdgDirectory

-- | For data files (e.g. images). It uses the XDG_DATA_HOME
--   environment variable. On non-Windows systems, the default is
--   ~/.local/share. On Windows, the default is %APPDATA%
--   (e.g. C:/Users/<user>/AppData/Roaming). Can be
--   considered as the user-specific equivalent of /usr/share.
XdgData :: XdgDirectory

-- | For configuration files. It uses the XDG_CONFIG_HOME
--   environment variable. On non-Windows systems, the default is
--   ~/.config. On Windows, the default is %APPDATA%
--   (e.g. C:/Users/<user>/AppData/Roaming). Can be
--   considered as the user-specific equivalent of /etc.
XdgConfig :: XdgDirectory

-- | For non-essential files (e.g. cache). It uses the
--   XDG_CACHE_HOME environment variable. On non-Windows systems,
--   the default is ~/.cache. On Windows, the default is
--   %LOCALAPPDATA% (e.g.
--   C:/Users/<user>/AppData/Local). Can be
--   considered as the user-specific equivalent of /var/cache.
XdgCache :: XdgDirectory

-- | For data that should persist between (application) restarts, but that
--   is not important or portable enough to the user that it should be
--   stored in XdgData. It uses the XDG_STATE_HOME
--   environment variable. On non-Windows sytems, the default is
--   ~/.local/state. On Windows, the default is
--   %LOCALAPPDATA% (e.g.
--   C:/Users/<user>/AppData/Local).
XdgState :: XdgDirectory
data () => Permissions

-- | A handle to a process, which can be used to wait for termination of
--   the process using waitForProcess.
--   
--   None of the process-creation functions in this library wait for
--   termination: they all return a ProcessHandle which may be used
--   to wait for the process later.
--   
--   On Windows a second wait method can be used to block for event
--   completion. This requires two handles. A process job handle and a
--   events handle to monitor.
data () => ProcessHandle
data () => StdStream

-- | Inherit Handle from parent
Inherit :: StdStream

-- | Use the supplied Handle
UseHandle :: Handle -> StdStream

-- | Create a new pipe. The returned Handle will use the default
--   encoding and newline translation mode (just like Handles
--   created by openFile).
CreatePipe :: StdStream

-- | Close the stream's file descriptor without passing a Handle. On POSIX
--   systems this may lead to strange behavior in the child process because
--   attempting to read or write after the file has been closed throws an
--   error. This should only be used with child processes that don't use
--   the file descriptor at all. If you wish to ignore the child process's
--   output you should either create a pipe and drain it manually or pass a
--   Handle that writes to /dev/null.
NoStream :: StdStream
data () => CmdSpec

-- | A command line to execute using the shell
ShellCommand :: String -> CmdSpec

-- | The name of an executable with a list of arguments
--   
--   The FilePath argument names the executable, and is interpreted
--   according to the platform's standard policy for searching for
--   executables. Specifically:
--   
--   
--   
- on Unix systems the execvp(3) semantics is used, where if
--   the executable filename does not contain a slash (/) then the
--   PATH environment variable is searched for the
--   executable.
--   
- on Windows systems the Win32 CreateProcess semantics is
--   used. Briefly: if the filename does not contain a path, then the
--   directory containing the parent executable is searched, followed by
--   the current directory, then some standard locations, and finally the
--   current PATH. An .exe extension is added if the
--   filename does not already have an extension. For full details see the
--   documentation for the Windows SearchPath API.
--   
--   
--   Windows does not have a mechanism for passing multiple arguments. When
--   using RawCommand on Windows, the command line is serialised
--   into a string, with arguments quoted separately. Command line parsing
--   is up individual programs, so the default behaviour may not work for
--   some programs. If you are not getting the desired results, construct
--   the command line yourself and use ShellCommand.
RawCommand :: FilePath -> [String] -> CmdSpec
data () => CreateProcess
CreateProcess :: CmdSpec -> Maybe FilePath -> Maybe [(String, String)] -> StdStream -> StdStream -> StdStream -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Maybe GroupID -> Maybe UserID -> Bool -> CreateProcess

-- | Executable & arguments, or shell command. If cwd is
--   Nothing, relative paths are resolved with respect to the
--   current working directory. If cwd is provided, it is
--   implementation-dependent whether relative paths are resolved with
--   respect to cwd or the current working directory, so absolute
--   paths should be used to ensure portability.
[cmdspec] :: CreateProcess -> CmdSpec

-- | Optional path to the working directory for the new process
[cwd] :: CreateProcess -> Maybe FilePath

-- | Optional environment (otherwise inherit from the current process)
[env] :: CreateProcess -> Maybe [(String, String)]

-- | How to determine stdin
[std_in] :: CreateProcess -> StdStream

-- | How to determine stdout
[std_out] :: CreateProcess -> StdStream

-- | How to determine stderr
[std_err] :: CreateProcess -> StdStream

-- | Close all file descriptors except stdin, stdout and stderr in the new
--   process (on Windows, only works if std_in, std_out, and std_err are
--   all Inherit). This implementation will call close on every fd from 3
--   to the maximum of open files, which can be slow for high maximum of
--   open files. XXX verify what happens with fds in nodejs child processes
[close_fds] :: CreateProcess -> Bool

-- | Create a new process group. On JavaScript this also creates a new
--   session.
[create_group] :: CreateProcess -> Bool

-- | Delegate control-C handling. Use this for interactive console
--   processes to let them handle control-C themselves (see below for
--   details).
[delegate_ctlc] :: CreateProcess -> Bool

-- | Use the windows DETACHED_PROCESS flag when creating the process; does
--   nothing on other platforms.
[detach_console] :: CreateProcess -> Bool

-- | Use the windows CREATE_NEW_CONSOLE flag when creating the process;
--   does nothing on other platforms.
--   
--   Default: False
[create_new_console] :: CreateProcess -> Bool

-- | Use posix setsid to start the new process in a new session; starts
--   process in a new session on JavaScript; does nothing on other
--   platforms.
[new_session] :: CreateProcess -> Bool

-- | Use posix setgid to set child process's group id; works for JavaScript
--   when system running nodejs is posix. does nothing on other platforms.
--   
--   Default: Nothing
[child_group] :: CreateProcess -> Maybe GroupID

-- | Use posix setuid to set child process's user id; works for JavaScript
--   when system running nodejs is posix. does nothing on other platforms.
--   
--   Default: Nothing
[child_user] :: CreateProcess -> Maybe UserID

-- | On Windows systems this flag indicates that we should wait for the
--   entire process tree to finish before unblocking. On POSIX systems this
--   flag is ignored. See $exec-on-windows for details.
--   
--   Default: False
[use_process_jobs] :: CreateProcess -> Bool

-- | The platform specific type for a process identifier.
--   
--   This is always an integral type. Width and signedness are platform
--   specific.
type Pid = CPid
data () => Layout
LayoutWide :: Maybe Int -> Layout
LayoutTall :: Layout
LayoutBare :: Layout
LayoutTidy :: Layout

-- | The data type SourcePos represents source positions. It
--   contains the name of the source file, a line number, and a column
--   number. Source line and column positions change intensively during
--   parsing, so we need to make them strict to avoid memory leaks.
data () => SourcePos
SourcePos :: FilePath -> !Pos -> !Pos -> SourcePos

-- | Name of source file
[sourceName] :: SourcePos -> FilePath

-- | Line number
[sourceLine] :: SourcePos -> !Pos

-- | Column number
[sourceColumn] :: SourcePos -> !Pos

-- | The main data structure defining a test suite.
--   
--   It consists of individual test cases and properties, organized in
--   named groups which form a tree-like hierarchy.
--   
--   There is no generic way to create a test case. Instead, every test
--   provider (tasty-hunit, tasty-smallcheck etc.) provides a function to
--   turn a test case into a TestTree.
--   
--   Groups can be created using testGroup.
data () => TestTree

-- | These are the two ways in which one test may depend on the others.
--   
--   This is the same distinction as the hard vs soft dependencies in
--   TestNG.
data () => DependencyType

-- | The current test tree will be executed after its dependencies finish,
--   and only if all of the dependencies succeed.
AllSucceed :: DependencyType

-- | The current test tree will be executed after its dependencies finish,
--   regardless of whether they succeed or not.
AllFinish :: DependencyType

-- | The name of a test or a group of tests
type TestName = String

-- | An error message arising during a regular expression operation. Eg:
--   trying to compile a malformed regular expression, or trying to apply a
--   malformed replacement pattern.
type RegexError = String

-- | A replacement pattern. May include numeric backreferences (N).
type Replacement = String

-- | Regular expression. Extended regular expression-ish syntax ? But does
--   not support eg (?i) syntax.
data () => Regexp

-- | A Ledger has the journal it derives from, and the accounts derived
--   from that. Accounts are accessible both list-wise and tree-wise, since
--   each one knows its parent and subs; the first account is the root of
--   the tree and always exists.
data () => Ledger
Ledger :: Journal -> [Account] -> Ledger
[ljournal] :: Ledger -> Journal
[laccounts] :: Ledger -> [Account]

-- | Whether an account's balance is normally a positive number (in
--   accounting terms, a debit balance) or a negative number (credit
--   balance). Assets and expenses are normally positive (debit), while
--   liabilities, equity and income are normally negative (credit).
--   https://en.wikipedia.org/wiki/Normal_balance
data () => NormalSign
NormallyPositive :: NormalSign
NormallyNegative :: NormalSign

-- | An account, with its balances, parent/subaccount relationships, etc.
--   Only the name is required; the other fields are added when needed.
data () => Account
Account :: AccountName -> Maybe AccountDeclarationInfo -> [Account] -> Maybe Account -> Bool -> Int -> MixedAmount -> MixedAmount -> Account

-- | this account's full name
[aname] :: Account -> AccountName

-- | optional extra info from account directives relationships in the tree
[adeclarationinfo] :: Account -> Maybe AccountDeclarationInfo

-- | this account's sub-accounts
[asubs] :: Account -> [Account]

-- | parent account
[aparent] :: Account -> Maybe Account

-- | used in the accounts report to label elidable parents balance
--   information
[aboring] :: Account -> Bool

-- | the number of postings to this account
[anumpostings] :: Account -> Int

-- | this account's balance, excluding subaccounts
[aebalance] :: Account -> MixedAmount

-- | this account's balance, including subaccounts
[aibalance] :: Account -> MixedAmount

-- | Extra information about an account that can be derived from its
--   account directive (and the other account directives).
data () => AccountDeclarationInfo
AccountDeclarationInfo :: Text -> [Tag] -> Int -> SourcePos -> AccountDeclarationInfo

-- | any comment lines following an account directive for this account
[adicomment] :: AccountDeclarationInfo -> Text

-- | tags extracted from the account comment, if any
[aditags] :: AccountDeclarationInfo -> [Tag]

-- | the order in which this account was declared, relative to other
--   account declarations, during parsing (1..)
[adideclarationorder] :: AccountDeclarationInfo -> Int

-- | source file and position
[adisourcepos] :: AccountDeclarationInfo -> SourcePos

-- | Extra information found in a tag directive.
newtype () => TagDeclarationInfo
TagDeclarationInfo :: Text -> TagDeclarationInfo

-- | any comment lines following the tag directive. No tags allowed here.
[tdicomment] :: TagDeclarationInfo -> Text

-- | Extra information found in a payee directive.
data () => PayeeDeclarationInfo
PayeeDeclarationInfo :: Text -> [Tag] -> PayeeDeclarationInfo

-- | any comment lines following the payee directive
[pdicomment] :: PayeeDeclarationInfo -> Text

-- | tags extracted from the comment, if any
[pditags] :: PayeeDeclarationInfo -> [Tag]

-- | The id of a data format understood by hledger, eg journal or
--   csv. The --output-format option selects one of these for
--   output.
type StorageFormat = String

-- | A journal in the process of being parsed, not yet finalised. The data
--   is partial, and list fields are in reverse order.
type ParsedJournal = Journal

-- | A Journal, containing transactions and various other things. The basic
--   data model for hledger.
--   
--   This is used during parsing (as the type alias ParsedJournal), and
--   then finalised/validated for use as a Journal. Some extra
--   parsing-related fields are included for convenience, at least for now.
--   In a ParsedJournal these are updated as parsing proceeds, in a Journal
--   they represent the final state at end of parsing (used eg by the add
--   command).
data () => Journal
Journal :: Maybe Year -> Maybe (CommoditySymbol, AmountStyle) -> Maybe DecimalMark -> [AccountName] -> [AccountAlias] -> [TimeclockEntry] -> [FilePath] -> [(Payee, PayeeDeclarationInfo)] -> [(TagName, TagDeclarationInfo)] -> [(AccountName, AccountDeclarationInfo)] -> Map AccountName [Tag] -> Map AccountType [AccountName] -> Map AccountName AccountType -> Map CommoditySymbol AmountStyle -> Map CommoditySymbol Commodity -> Map CommoditySymbol AmountStyle -> [PriceDirective] -> [MarketPrice] -> [TransactionModifier] -> [PeriodicTransaction] -> [Transaction] -> Text -> [(FilePath, Text)] -> POSIXTime -> Journal

-- | the current default year, specified by the most recent Y directive (or
--   current date)
[jparsedefaultyear] :: Journal -> Maybe Year

-- | the current default commodity and its format, specified by the most
--   recent D directive
[jparsedefaultcommodity] :: Journal -> Maybe (CommoditySymbol, AmountStyle)

-- | the character to always parse as decimal point, if set by CsvReader's
--   decimal-mark (or a future journal directive)
[jparsedecimalmark] :: Journal -> Maybe DecimalMark

-- | the current stack of parent account names, specified by apply account
--   directives
[jparseparentaccounts] :: Journal -> [AccountName]

-- | the current account name aliases in effect, specified by alias
--   directives (& options ?) ,jparsetransactioncount :: Integer -- ^
--   the current count of transactions parsed so far (only journal format
--   txns, currently)
[jparsealiases] :: Journal -> [AccountAlias]

-- | timeclock sessions which have not been clocked out
[jparsetimeclockentries] :: Journal -> [TimeclockEntry]
[jincludefilestack] :: Journal -> [FilePath]

-- | Payees declared by payee directives, in parse order (after journal
--   finalisation)
[jdeclaredpayees] :: Journal -> [(Payee, PayeeDeclarationInfo)]

-- | Tags declared by tag directives, in parse order (after journal
--   finalisation)
[jdeclaredtags] :: Journal -> [(TagName, TagDeclarationInfo)]

-- | Accounts declared by account directives, in parse order (after journal
--   finalisation)
[jdeclaredaccounts] :: Journal -> [(AccountName, AccountDeclarationInfo)]

-- | Accounts which have tags declared in their directives, and those tags.
--   (Does not include parents' tags.)
[jdeclaredaccounttags] :: Journal -> Map AccountName [Tag]

-- | Accounts whose type has been explicitly declared in their account
--   directives, grouped by type.
[jdeclaredaccounttypes] :: Journal -> Map AccountType [AccountName]

-- | All accounts for which a type has been declared or can be inferred
--   from its parent or its name.
[jaccounttypes] :: Journal -> Map AccountName AccountType

-- | per-commodity display styles declared globally, eg by command line
--   option or import command
[jglobalcommoditystyles] :: Journal -> Map CommoditySymbol AmountStyle

-- | commodities and formats declared by commodity directives
[jcommodities] :: Journal -> Map CommoditySymbol Commodity

-- | commodities and formats inferred from journal amounts
[jinferredcommodities] :: Journal -> Map CommoditySymbol AmountStyle

-- | Declarations of market prices by P directives, in parse order (after
--   journal finalisation)
[jpricedirectives] :: Journal -> [PriceDirective]

-- | Market prices implied by transactions, in parse order (after journal
--   finalisation)
[jinferredmarketprices] :: Journal -> [MarketPrice]
[jtxnmodifiers] :: Journal -> [TransactionModifier]
[jperiodictxns] :: Journal -> [PeriodicTransaction]
[jtxns] :: Journal -> [Transaction]

-- | any final trailing comments in the (main) journal file
[jfinalcommentlines] :: Journal -> Text

-- | the file path and raw text of the main and any included journal files.
--   The main file is first, followed by any included files in the order
--   encountered. TODO: FilePath is a sloppy type here, don't assume it's a
--   real file; values like "", "-", "(string)" can be seen
[jfiles] :: Journal -> [(FilePath, Text)]

-- | when this journal was last read from its file(s) NOTE: after adding
--   new fields, eg involving account names, consider updating the Anon
--   instance in Hleger.Cli.Anon
[jlastreadtime] :: Journal -> POSIXTime

-- | A historical market price (exchange rate) from one commodity to
--   another. A more concise form of a PriceDirective, without the amount
--   display info.
data () => MarketPrice
MarketPrice :: Day -> CommoditySymbol -> CommoditySymbol -> Quantity -> MarketPrice

-- | Date on which this price becomes effective.
[mpdate] :: MarketPrice -> Day

-- | The commodity being converted from.
[mpfrom] :: MarketPrice -> CommoditySymbol

-- | The commodity being converted to.
[mpto] :: MarketPrice -> CommoditySymbol

-- | One unit of the "from" commodity is worth this quantity of the "to"
--   commodity.
[mprate] :: MarketPrice -> Quantity

-- | A market price declaration made by the journal format's P directive.
--   It declares two things: a historical exchange rate between two
--   commodities, and an amount display style for the second commodity.
data () => PriceDirective
PriceDirective :: Day -> CommoditySymbol -> Amount -> PriceDirective
[pddate] :: PriceDirective -> Day
[pdcommodity] :: PriceDirective -> CommoditySymbol
[pdamount] :: PriceDirective -> Amount
data () => TimeclockEntry
TimeclockEntry :: SourcePos -> TimeclockCode -> LocalTime -> AccountName -> Text -> Text -> [Tag] -> TimeclockEntry
[tlsourcepos] :: TimeclockEntry -> SourcePos
[tlcode] :: TimeclockEntry -> TimeclockCode
[tldatetime] :: TimeclockEntry -> LocalTime
[tlaccount] :: TimeclockEntry -> AccountName
[tldescription] :: TimeclockEntry -> Text
[tlcomment] :: TimeclockEntry -> Text
[tltags] :: TimeclockEntry -> [Tag]
data () => TimeclockCode
SetBalance :: TimeclockCode
SetRequiredHours :: TimeclockCode
In :: TimeclockCode
Out :: TimeclockCode
FinalOut :: TimeclockCode

-- | A periodic transaction rule, describing a transaction that recurs.
data () => PeriodicTransaction
PeriodicTransaction :: Text -> Interval -> DateSpan -> (SourcePos, SourcePos) -> Status -> Text -> Text -> Text -> [Tag] -> [Posting] -> PeriodicTransaction

-- | the period expression as written
[ptperiodexpr] :: PeriodicTransaction -> Text

-- | the interval at which this transaction recurs
[ptinterval] :: PeriodicTransaction -> Interval

-- | the (possibly unbounded) period during which this transaction recurs.
--   Contains a whole number of intervals.
[ptspan] :: PeriodicTransaction -> DateSpan

-- | the file position where the period expression starts, and where the
--   last posting ends
[ptsourcepos] :: PeriodicTransaction -> (SourcePos, SourcePos)

-- | some of Transaction's fields
[ptstatus] :: PeriodicTransaction -> Status
[ptcode] :: PeriodicTransaction -> Text
[ptdescription] :: PeriodicTransaction -> Text
[ptcomment] :: PeriodicTransaction -> Text
[pttags] :: PeriodicTransaction -> [Tag]
[ptpostings] :: PeriodicTransaction -> [Posting]

-- | A transaction modifier transformation, which adds an extra posting to
--   the matched posting's transaction. Can be like a regular posting, or
--   can have the tmprIsMultiplier flag set, indicating that it's a
--   multiplier for the matched posting's amount.
data () => TMPostingRule
TMPostingRule :: Posting -> Bool -> TMPostingRule
[tmprPosting] :: TMPostingRule -> Posting
[tmprIsMultiplier] :: TMPostingRule -> Bool

-- | A transaction modifier rule. This has a query which matches postings
--   in the journal, and a list of transformations to apply to those
--   postings or their transactions. Currently there is one kind of
--   transformation: the TMPostingRule, which adds a posting ("auto
--   posting") to the transaction, optionally setting its amount to the
--   matched posting's amount multiplied by a constant.
data () => TransactionModifier
TransactionModifier :: Text -> [TMPostingRule] -> TransactionModifier
[tmquerytxt] :: TransactionModifier -> Text
[tmpostingrules] :: TransactionModifier -> [TMPostingRule]
data () => Transaction
Transaction :: Integer -> Text -> (SourcePos, SourcePos) -> Day -> Maybe Day -> Status -> Text -> Text -> Text -> [Tag] -> [Posting] -> Transaction

-- | this transaction's 1-based position in the transaction stream, or 0
--   when not available
[tindex] :: Transaction -> Integer

-- | any comment lines immediately preceding this transaction
[tprecedingcomment] :: Transaction -> Text

-- | the file position where the date starts, and where the last posting
--   ends
[tsourcepos] :: Transaction -> (SourcePos, SourcePos)
[tdate] :: Transaction -> Day
[tdate2] :: Transaction -> Maybe Day
[tstatus] :: Transaction -> Status
[tcode] :: Transaction -> Text
[tdescription] :: Transaction -> Text

-- | this transaction's comment lines, as a single non-indented multi-line
--   string
[tcomment] :: Transaction -> Text

-- | tag names and values, extracted from the comment
[ttags] :: Transaction -> [Tag]

-- | this transaction's postings
[tpostings] :: Transaction -> [Posting]
data () => Posting
Posting :: Maybe Day -> Maybe Day -> Status -> AccountName -> MixedAmount -> Text -> PostingType -> [Tag] -> Maybe BalanceAssertion -> Maybe Transaction -> Maybe Posting -> Posting

-- | this posting's date, if different from the transaction's
[pdate] :: Posting -> Maybe Day

-- | this posting's secondary date, if different from the transaction's
[pdate2] :: Posting -> Maybe Day
[pstatus] :: Posting -> Status
[paccount] :: Posting -> AccountName
[pamount] :: Posting -> MixedAmount

-- | this posting's comment lines, as a single non-indented multi-line
--   string
[pcomment] :: Posting -> Text
[ptype] :: Posting -> PostingType

-- | tag names and values, extracted from the posting comment and (after
--   finalisation) the posting account's directive if any
[ptags] :: Posting -> [Tag]

-- | an expected balance in the account after this posting, in a single
--   commodity, excluding subaccounts.
[pbalanceassertion] :: Posting -> Maybe BalanceAssertion

-- | this posting's parent transaction (co-recursive types). Tying this
--   knot gets tedious, Maybe makes it easier/optional.
[ptransaction] :: Posting -> Maybe Transaction

-- | When this posting has been transformed in some way (eg its amount or
--   price was inferred, or the account name was changed by a pivot or
--   budget report), this references the original untransformed posting
--   (which will have Nothing in this field).
[poriginal] :: Posting -> Maybe Posting

-- | A balance assertion is a declaration about an account's expected
--   balance at a certain point (posting date and parse order). They
--   provide additional error checking and readability to a journal file.
--   
--   A balance assignments is an instruction to hledger to adjust an
--   account's balance to a certain amount at a certain point.
--   
--   The BalanceAssertion type is used for representing both of
--   these.
--   
--   hledger supports multiple kinds of balance assertions/assignments,
--   which differ in whether they refer to a single commodity or all
--   commodities, and the (subaccount-)inclusive or exclusive account
--   balance.
data () => BalanceAssertion
BalanceAssertion :: Amount -> Bool -> Bool -> SourcePos -> BalanceAssertion

-- | the expected balance in a particular commodity
[baamount] :: BalanceAssertion -> Amount

-- | disallow additional non-asserted commodities ?
[batotal] :: BalanceAssertion -> Bool

-- | include subaccounts when calculating the actual balance ?
[bainclusive] :: BalanceAssertion -> Bool

-- | the assertion's file position, for error reporting
[baposition] :: BalanceAssertion -> SourcePos

-- | The status of a transaction or posting, recorded with a status mark
--   (nothing, !, or *). What these mean is ultimately user defined.
data () => Status
Unmarked :: Status
Pending :: Status
Cleared :: Status
type DateTag = (TagName, Day)
type Tag = (TagName, TagValue)
type TagValue = Text
type TagName = Text
data () => PostingType
RegularPosting :: PostingType
VirtualPosting :: PostingType
BalancedVirtualPosting :: PostingType
data () => MixedAmount

-- | Types with this class have one or more amounts, which can have display
--   styles applied to them.
class () => HasAmounts a
styleAmounts :: HasAmounts a => Map CommoditySymbol AmountStyle -> a -> a
data () => Amount
Amount :: !CommoditySymbol -> !Quantity -> !AmountStyle -> !Maybe AmountPrice -> Amount
[acommodity] :: Amount -> !CommoditySymbol
[aquantity] :: Amount -> !Quantity
[astyle] :: Amount -> !AmountStyle

-- | the (fixed, transaction-specific) price for this amount, if any
[aprice] :: Amount -> !Maybe AmountPrice
data () => Commodity
Commodity :: CommoditySymbol -> Maybe AmountStyle -> Commodity
[csymbol] :: Commodity -> CommoditySymbol
[cformat] :: Commodity -> Maybe AmountStyle
type CommoditySymbol = Text

-- | A style for displaying digit groups in the integer part of a floating
--   point number. It consists of the character used to separate groups
--   (comma or period, whichever is not used as decimal point), and the
--   size of each group, starting with the one nearest the decimal point.
--   The last group size is assumed to repeat. Eg, comma between thousands
--   is DigitGroups ',' [3].
data () => DigitGroupStyle
DigitGroups :: !Char -> ![Word8] -> DigitGroupStyle

-- | "Rounding strategy" - how to apply an AmountStyle's display precision
--   to a posting amount (and its cost, if any). Mainly used to customise
--   print's output, with --round=none|soft|hard|all.
data () => Rounding

-- | keep display precisions unchanged in amt and cost
NoRounding :: Rounding

-- | do soft rounding of amt and cost amounts (show more or fewer decimal
--   zeros to approximate the target precision, but don't hide significant
--   digits)
SoftRounding :: Rounding

-- | do hard rounding of amt (use the exact target precision, possibly
--   hiding significant digits), and soft rounding of cost
HardRounding :: Rounding

-- | do hard rounding of amt and cost
AllRounding :: Rounding

-- | The "display precision" for a hledger amount, by which we mean the
--   number of decimal digits to display to the right of the decimal mark.
data () => AmountPrecision

-- | show this many decimal digits (0..255)
Precision :: !Word8 -> AmountPrecision

-- | show all significant decimal digits stored internally
NaturalPrecision :: AmountPrecision

-- | Every Amount has one of these, influencing how the amount is
--   displayed. Also, each Commodity can have one, which can be applied to
--   its amounts for consistent display. See also Amount.AmountDisplayOpts.
data () => AmountStyle
AmountStyle :: !Side -> !Bool -> !Maybe DigitGroupStyle -> !Maybe Char -> !AmountPrecision -> !Rounding -> AmountStyle

-- | show the symbol on the left or the right ?
[ascommodityside] :: AmountStyle -> !Side

-- | show a space between symbol and quantity ?
[ascommodityspaced] :: AmountStyle -> !Bool

-- | show the integer part with these digit group marks, or not
[asdigitgroups] :: AmountStyle -> !Maybe DigitGroupStyle

-- | show this character (should be . or ,) as decimal mark, or use the
--   default (.)
[asdecimalmark] :: AmountStyle -> !Maybe Char

-- | "display precision" - show this number of digits after the decimal
--   point
[asprecision] :: AmountStyle -> !AmountPrecision

-- | "rounding strategy" - kept here for convenience, for now: when
--   displaying an amount, it is ignored, but when applying this style to
--   another amount, it determines how hard we should try to adjust the
--   amount's display precision.
[asrounding] :: AmountStyle -> !Rounding

-- | An amount's per-unit or total cost/selling price in another commodity,
--   as recorded in the journal entry eg with  or @. Cost,
--   formerly AKA "transaction price". The amount is always positive.
data () => AmountPrice
UnitPrice :: !Amount -> AmountPrice
TotalPrice :: !Amount -> AmountPrice

-- | The basic numeric type used in amounts.
type Quantity = Decimal

-- | One of the decimal marks we support: either period or comma.
type DecimalMark = Char
data () => Side
L :: Side
R :: Side
data () => AccountAlias
BasicAlias :: AccountName -> AccountName -> AccountAlias
RegexAlias :: Regexp -> Replacement -> AccountAlias
data () => AccountType
Asset :: AccountType
Liability :: AccountType
Equity :: AccountType
Revenue :: AccountType
Expense :: AccountType

-- | a subtype of Asset - liquid assets to show in cashflow report
Cash :: AccountType

-- | a subtype of Equity - account in which to generate conversion postings
--   for transaction prices
Conversion :: AccountType
type AccountName = Text
type Payee = Text
data () => Interval
NoInterval :: Interval
Days :: Int -> Interval
Weeks :: Int -> Interval
Months :: Int -> Interval
Quarters :: Int -> Interval
Years :: Int -> Interval
DayOfMonth :: Int -> Interval
WeekdayOfMonth :: Int -> Int -> Interval
DaysOfWeek :: [Int] -> Interval
DayOfYear :: Int -> Int -> Interval

-- | Day of month, in range 1 to 31.
type DayOfMonth = Int
data () => Period
DayPeriod :: Day -> Period
WeekPeriod :: Day -> Period
MonthPeriod :: Year -> Month -> Period
QuarterPeriod :: Year -> Quarter -> Period
YearPeriod :: Year -> Period
PeriodBetween :: Day -> Day -> Period
PeriodFrom :: Day -> Period
PeriodTo :: Day -> Period
PeriodAll :: Period

-- | The class of types which can be represented as a period of days.
class Ord p => DayPeriod p

-- | Returns the first Day in a period of days.
periodFirstDay :: DayPeriod p => p -> Day

-- | Returns the last Day in a period of days.
periodLastDay :: DayPeriod p => p -> Day

-- | Get the period this day is in.
dayPeriod :: DayPeriod p => Day -> p

-- | A possibly open-ended span of time, from an optional inclusive start
--   date to an optional exclusive end date. Each date can be either exact
--   or flexible. An "exact date span" is a Datepan with exact start and
--   end dates.
data () => DateSpan
DateSpan :: Maybe EFDay -> Maybe EFDay -> DateSpan

-- | A date which is either exact or flexible. Flexible dates are allowed
--   to be adjusted in certain situations.
data () => EFDay
Exact :: Day -> EFDay
Flex :: Day -> EFDay
data () => WhichDate
PrimaryDate :: WhichDate
SecondaryDate :: WhichDate
data () => SmartInterval
Day :: SmartInterval
Week :: SmartInterval
Month :: SmartInterval
Quarter :: SmartInterval
Year :: SmartInterval

-- | The Modified Julian Day is a standard count of days, with zero being
--   the day 1858-11-17.
newtype () => Day
ModifiedJulianDay :: Integer -> Day
[toModifiedJulianDay] :: Day -> Integer
type Month = Int
type Quarter = Int

-- | A possibly incomplete year-month-day date provided by the user, to be
--   interpreted as either a date or a date span depending on context.
--   Missing parts "on the left" will be filled from the provided reference
--   date, e.g. if the year and month are missing, the reference date's
--   year and month are used. Missing parts "on the right" are assumed,
--   when interpreting as a date, to be 1, (e.g. if the year and month are
--   present but the day is missing, it means first day of that month); or
--   when interpreting as a date span, to be a wildcard (so it would mean
--   all days of that month). See the smartdate parser for more
--   examples.
--   
--   Or, one of the standard periods and an offset relative to the
--   reference date: (last|this|next) (day|week|month|quarter|year), where
--   "this" means the period containing the reference date.
data () => SmartDate
SmartCompleteDate :: Day -> SmartDate
SmartAssumeStart :: Year -> Maybe Month -> SmartDate
SmartFromReference :: Maybe Month -> MonthDay -> SmartDate
SmartMonth :: Month -> SmartDate
SmartRelative :: Integer -> SmartInterval -> SmartDate
type WeekDay = Int
type MonthDay = Int
type YearDay = Int
type MonthWeek = Int
type YearWeek = Int

-- | A specialised version of ParseErrorBundle: a non-empty collection of
--   hledger parse errors, equipped with PosState to help pretty-print
--   them. Specialised for a Text parse stream.
type HledgerParseErrors = ParseErrorBundle Text HledgerParseErrorData

-- | Custom error data for hledger parsers. Specialised for a Text
--   parse stream. ReparseableTextParseErrorData ?
data () => HledgerParseErrorData

-- | Helper for constructing Builders while keeping track of text width.
data () => WideBuilder
WideBuilder :: !Builder -> !Int -> WideBuilder
[wbBuilder] :: WideBuilder -> !Builder
[wbWidth] :: WideBuilder -> !Int

-- | A parser of text that runs in some monad.
type TextParser (m :: Type -> Type) a = ParsecT HledgerParseErrorData Text m a

-- | A parser of strict text to some type.
type SimpleTextParser = Parsec HledgerParseErrorData Text

-- | A parser of string to some type.
type SimpleStringParser a = Parsec HledgerParseErrorData String a

-- | The result of running cmdargs: an association list of option names to
--   string values.
data () => RawOpts

-- | An id identifying which report item field to interpolate. These are
--   drawn from several hledger report types, so are not all applicable for
--   a given report.
data () => ReportItemField

-- | A posting or balance report item's account name
AccountField :: ReportItemField

-- | A posting or register or entry report item's date
DefaultDateField :: ReportItemField

-- | A posting or register or entry report item's description
DescriptionField :: ReportItemField

-- | A balance or posting report item's balance or running total. Always
--   rendered right-justified.
TotalField :: ReportItemField

-- | A balance report item's indent level (which may be different from the
--   account name depth). Rendered as this number of spaces, multiplied by
--   the minimum width spec if any.
DepthSpacerField :: ReportItemField

-- | A report item's nth field. May be unimplemented.
FieldNo :: Int -> ReportItemField
data () => StringFormatComponent

-- | Literal text to be rendered as-is
FormatLiteral :: Text -> StringFormatComponent

-- | A data field to be formatted and interpolated. Parameters:
--   
--   
--   
- Left justify ? Right justified if false
--   
- Minimum width ? Will be space-padded if narrower than this
--   
- Maximum width ? Will be clipped if wider than this
--   
- Which of the standard hledger report item fields to
--   interpolate
--   
FormatField :: Bool -> Maybe Int -> Maybe Int -> ReportItemField -> StringFormatComponent

-- | A format specification/template to use when rendering a report line
--   item as text.
--   
--   A format is a sequence of components; each is either a literal string,
--   or a hledger report item field with specified width and justification
--   whose value will be interpolated at render time.
--   
--   A component's value may be a multi-line string (or a multi-commodity
--   amount), in which case the final string will be either single-line or
--   a top or bottom-aligned multi-line string depending on the
--   StringFormat variant used.
--   
--   Currently this is only used in the balance command's single-column
--   mode, which provides a limited StringFormat renderer.
data () => StringFormat

-- | multi-line values will be rendered on one line, comma-separated
OneLine :: [StringFormatComponent] -> StringFormat

-- | values will be top-aligned (and bottom-padded to the same height)
TopAligned :: [StringFormatComponent] -> StringFormat

-- | values will be bottom-aligned (and top-padded)
BottomAligned :: [StringFormatComponent] -> StringFormat

-- | Options for the display of Amount and MixedAmount. (ee also
--   Types.AmountStyle.
data () => AmountDisplayOpts
AmountDisplayOpts :: Bool -> Bool -> Maybe [CommoditySymbol] -> Bool -> Bool -> Bool -> Maybe Int -> Maybe Int -> Bool -> Bool -> AmountDisplayOpts

-- | Whether to display commodity symbols.
[displayCommodity] :: AmountDisplayOpts -> Bool

-- | Whether to display commodity symbols for zero Amounts.
[displayZeroCommodity] :: AmountDisplayOpts -> Bool

-- | For a MixedAmount, an optional order in which to display the
--   commodities. Also, causes 0s to be generated for any commodities which
--   are not present (important for tabular reports).
[displayCommodityOrder] :: AmountDisplayOpts -> Maybe [CommoditySymbol]

-- | Whether to display digit group marks (eg thousands separators)
[displayDigitGroups] :: AmountDisplayOpts -> Bool

-- | Whether to add a trailing decimal mark when there are no decimal
--   digits and there are digit group marks, to disambiguate
[displayForceDecimalMark] :: AmountDisplayOpts -> Bool

-- | Whether to display on one line.
[displayOneLine] :: AmountDisplayOpts -> Bool

-- | Minimum width to pad to
[displayMinWidth] :: AmountDisplayOpts -> Maybe Int

-- | Maximum width to clip to
[displayMaxWidth] :: AmountDisplayOpts -> Maybe Int

-- | Whether to display Amounts' costs.
[displayCost] :: AmountDisplayOpts -> Bool

-- | Whether to ansi-colourise negative Amounts.
[displayColour] :: AmountDisplayOpts -> Bool

-- | A price oracle is a magic memoising function that efficiently looks up
--   market prices (exchange rates) from one commodity to another (or if
--   unspecified, to a default valuation commodity) on a given date.
type PriceOracle = (Day, CommoditySymbol, Maybe CommoditySymbol) -> Maybe (CommoditySymbol, Quantity)

-- | What kind of value conversion should be done on amounts ? CLI:
--   --value=then|end|now|DATE[,COMM]
data () => ValuationType

-- | convert to default or given valuation commodity, using market prices
--   at each posting's date
AtThen :: Maybe CommoditySymbol -> ValuationType

-- | convert to default or given valuation commodity, using market prices
--   at period end(s)
AtEnd :: Maybe CommoditySymbol -> ValuationType

-- | convert to default or given valuation commodity, using current market
--   prices
AtNow :: Maybe CommoditySymbol -> ValuationType

-- | convert to default or given valuation commodity, using market prices
--   on some date
AtDate :: Day -> Maybe CommoditySymbol -> ValuationType

-- | Which operation to perform on conversion transactions. (There was also
--   an "infer equity postings" operation, but that is now done earlier, in
--   journal finalisation.)
data () => ConversionOp
NoConversionOp :: ConversionOp
ToCost :: ConversionOp

-- | A query option changes a query's/report's behaviour and output in some
--   way.
data () => QueryOpt

-- | show an account register focussed on this account
QueryOptInAcctOnly :: AccountName -> QueryOpt

-- | as above but include sub-accounts in the account register |
--   QueryOptCostBasis -- ^ show amounts converted to cost where possible |
--   QueryOptDate2 -- ^ show secondary dates instead of primary dates
QueryOptInAcct :: AccountName -> QueryOpt

-- | A more expressive Ord, used for amt: queries. The Abs* variants
--   compare with the absolute value of a number, ignoring sign.
data () => OrdPlus
Lt :: OrdPlus
LtEq :: OrdPlus
Gt :: OrdPlus
GtEq :: OrdPlus
Eq :: OrdPlus
AbsLt :: OrdPlus
AbsLtEq :: OrdPlus
AbsGt :: OrdPlus
AbsGtEq :: OrdPlus
AbsEq :: OrdPlus

-- | A query is a composition of search criteria, which can be used to
--   match postings, transactions, accounts and more.
data () => Query

-- | negate this match
Not :: Query -> Query

-- | match if all of these match
And :: [Query] -> Query

-- | match if any of these match no-op queries
Or :: [Query] -> Query

-- | always match
Any :: Query

-- | never match data queries (in "standard" order, roughly as they appear
--   in a transaction)
None :: Query

-- | match primary dates in this date span
Date :: DateSpan -> Query

-- | match secondary dates in this date span
Date2 :: DateSpan -> Query

-- | match this txn/posting status
StatusQ :: Status -> Query

-- | match txn codes infix-matched by this regexp
Code :: Regexp -> Query

-- | match txn descriptions infix-matched by this regexp
Desc :: Regexp -> Query

-- | match if a tag's name, and optionally its value, is infix-matched by
--   the respective regexps
Tag :: Regexp -> Maybe Regexp -> Query

-- | match account names infix-matched by this regexp
Acct :: Regexp -> Query

-- | match accounts whose type is one of these (or with no types, any
--   account)
Type :: [AccountType] -> Query

-- | match if account depth is less than or equal to this value (or,
--   sometimes used as a display option)
Depth :: Int -> Query

-- | match postings with this "realness" value
Real :: Bool -> Query

-- | match if the amount's numeric quantity is less thangreater
--   thanequal to/unsignedly equal to some value
Amt :: OrdPlus -> Quantity -> Query

-- | match if the commodity symbol is fully-matched by this regexp
Sym :: Regexp -> Query

-- | A parser of text that runs in some monad, keeping a Journal as state,
--   that can throw an exception to end parsing, preventing further parser
--   backtracking.
type ErroringJournalParser (m :: Type -> Type) a = StateT Journal ParsecT HledgerParseErrorData Text ExceptT FinalParseError m a

-- | A parser of text that runs in some monad, keeping a Journal as state.
type JournalParser (m :: Type -> Type) a = StateT Journal ParsecT HledgerParseErrorData Text m a
data () => BalancingOpts
BalancingOpts :: Bool -> Bool -> Maybe (Map CommoditySymbol AmountStyle) -> BalancingOpts

-- | should failing balance assertions be ignored ?
[ignore_assertions_] :: BalancingOpts -> Bool

-- | Are we permitted to infer missing costs to balance transactions ?
--   Distinct from InputOpts{infer_costs_}.
[infer_balancing_costs_] :: BalancingOpts -> Bool

-- | commodity display styles
[commodity_styles_] :: BalancingOpts -> Maybe (Map CommoditySymbol AmountStyle)
class () => HasBalancingOpts c
balancingOpts :: HasBalancingOpts c => Lens' c BalancingOpts
commodity_styles :: HasBalancingOpts c => Lens' c (Maybe (Map CommoditySymbol AmountStyle))
ignore_assertions :: HasBalancingOpts c => Lens' c Bool
infer_balancing_costs :: HasBalancingOpts c => Lens' c Bool
data () => InputOpts
InputOpts :: Maybe StorageFormat -> Maybe FilePath -> [String] -> Bool -> Bool -> Bool -> String -> Maybe DateSpan -> Bool -> DateSpan -> Bool -> Bool -> Bool -> BalancingOpts -> Bool -> Day -> InputOpts

-- | a file/storage format to try, unless overridden by a filename prefix.
--   Nothing means try all.
[mformat_] :: InputOpts -> Maybe StorageFormat

-- | a conversion rules file to use (when reading CSV)
[mrules_file_] :: InputOpts -> Maybe FilePath

-- | account name aliases to apply
[aliases_] :: InputOpts -> [String]

-- | do light obfuscation of the data. Now corresponds to --obfuscate, not
--   the old --anon flag.
[anon_] :: InputOpts -> Bool

-- | read only new transactions since this file was last read
[new_] :: InputOpts -> Bool

-- | save latest new transactions state for next time
[new_save_] :: InputOpts -> Bool

-- | use the given field's value as the account name
[pivot_] :: InputOpts -> String

-- | span in which to generate forecast transactions
[forecast_] :: InputOpts -> Maybe DateSpan

-- | add user-visible tags when generating/modifying transactions &
--   postings ?
[verbose_tags_] :: InputOpts -> Bool

-- | a dirty hack keeping the query dates in InputOpts. This rightfully
--   lives in ReportSpec, but is duplicated here.
[reportspan_] :: InputOpts -> DateSpan

-- | generate automatic postings when journal is parsed ?
[auto_] :: InputOpts -> Bool

-- | infer equity conversion postings from costs ?
[infer_equity_] :: InputOpts -> Bool

-- | infer costs from equity conversion postings ? distinct from
--   BalancingOpts{infer_balancing_costs_}
[infer_costs_] :: InputOpts -> Bool

-- | options for balancing transactions
[balancingopts_] :: InputOpts -> BalancingOpts

-- | do extra error checking (eg, all posted accounts are declared, no
--   prices are inferred)
[strict_] :: InputOpts -> Bool

-- | today's date, for use with forecast transactions XXX this duplicates
--   _rsDay, and should eventually be removed when it's not needed anymore.
[_ioDay] :: InputOpts -> Day
class () => HasInputOpts c
inputOpts :: HasInputOpts c => Lens' c InputOpts
aliases :: HasInputOpts c => Lens' c [String]
anon__ :: HasInputOpts c => Lens' c Bool
auto__ :: HasInputOpts c => Lens' c Bool
balancingopts :: HasInputOpts c => Lens' c BalancingOpts
forecast :: HasInputOpts c => Lens' c (Maybe DateSpan)
infer_costs :: HasInputOpts c => Lens' c Bool
infer_equity :: HasInputOpts c => Lens' c Bool
ioDay :: HasInputOpts c => Lens' c Day
mformat :: HasInputOpts c => Lens' c (Maybe StorageFormat)
mrules_file :: HasInputOpts c => Lens' c (Maybe FilePath)
new__ :: HasInputOpts c => Lens' c Bool
new_save :: HasInputOpts c => Lens' c Bool
pivot :: HasInputOpts c => Lens' c String
reportspan :: HasInputOpts c => Lens' c DateSpan
strict :: HasInputOpts c => Lens' c Bool
verbose_tags :: HasInputOpts c => Lens' c Bool

-- | A fully-determined set of report parameters (report options with all
--   partial values made total, eg the begin and end dates are known,
--   avoiding date/regex errors; plus the reporting date), and the query
--   successfully calculated from them.
--   
--   If you change the report options or date in one of these, you should
--   use reportOptsToSpec to regenerate the whole thing, avoiding
--   inconsistency.
data () => ReportSpec
ReportSpec :: ReportOpts -> Day -> Query -> [QueryOpt] -> ReportSpec

-- | The underlying ReportOpts used to generate this ReportSpec
[_rsReportOpts] :: ReportSpec -> ReportOpts

-- | The Day this ReportSpec is generated for
[_rsDay] :: ReportSpec -> Day

-- | The generated Query for the given day
[_rsQuery] :: ReportSpec -> Query

-- | A list of QueryOpts for the given day
[_rsQueryOpts] :: ReportSpec -> [QueryOpt]

-- | Standard options for customising report filtering and output. Most of
--   these correspond to standard hledger command-line options or query
--   arguments, but not all. Some are used only by certain commands, as
--   noted below.
data () => ReportOpts
ReportOpts :: Period -> Interval -> [Status] -> Maybe ConversionOp -> Maybe ValuationType -> Bool -> Maybe Int -> Bool -> Bool -> Bool -> Bool -> StringFormat -> Bool -> [Text] -> Bool -> Bool -> Bool -> BalanceCalculation -> BalanceAccumulation -> Maybe Text -> AccountListMode -> Int -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Maybe NormalSign -> Bool -> Bool -> Layout -> ReportOpts
[period_] :: ReportOpts -> Period
[interval_] :: ReportOpts -> Interval

-- | Zero, one, or two statuses to be matched
[statuses_] :: ReportOpts -> [Status]

-- | Which operation should we apply to conversion transactions?
[conversionop_] :: ReportOpts -> Maybe ConversionOp

-- | What value should amounts be converted to ?
[value_] :: ReportOpts -> Maybe ValuationType

-- | Infer market prices from transactions ?
[infer_prices_] :: ReportOpts -> Bool
[depth_] :: ReportOpts -> Maybe Int
[date2_] :: ReportOpts -> Bool
[empty_] :: ReportOpts -> Bool
[no_elide_] :: ReportOpts -> Bool
[real_] :: ReportOpts -> Bool
[format_] :: ReportOpts -> StringFormat
[pretty_] :: ReportOpts -> Bool
[querystring_] :: ReportOpts -> [Text]
[average_] :: ReportOpts -> Bool
[related_] :: ReportOpts -> Bool
[txn_dates_] :: ReportOpts -> Bool

-- | What to calculate in balance report cells
[balancecalc_] :: ReportOpts -> BalanceCalculation

-- | How to accumulate balance report values over time
[balanceaccum_] :: ReportOpts -> BalanceAccumulation

-- | A case-insensitive description substring to select periodic
--   transactions for budget reports. (Not a regexp, nor a full hledger
--   query, for now.)
[budgetpat_] :: ReportOpts -> Maybe Text
[accountlistmode_] :: ReportOpts -> AccountListMode
[drop_] :: ReportOpts -> Int

-- | Include accounts declared but not yet posted to ?
[declared_] :: ReportOpts -> Bool
[row_total_] :: ReportOpts -> Bool
[no_total_] :: ReportOpts -> Bool
[summary_only_] :: ReportOpts -> Bool

-- | Show costs for reports which normally don't show them ?
[show_costs_] :: ReportOpts -> Bool
[sort_amount_] :: ReportOpts -> Bool
[percent_] :: ReportOpts -> Bool

-- | Flip all amount signs in reports ?
[invert_] :: ReportOpts -> Bool

-- | This can be set when running balance reports on a set of accounts with
--   the same normal balance type (eg all assets, or all incomes). - It
--   helps --sort-amount know how to sort negative numbers (eg in the
--   income section of an income statement) - It helps compound balance
--   report commands (is, bs etc.) do sign normalisation, converting
--   normally negative subreports to normally positive for a more
--   conventional display.
[normalbalance_] :: ReportOpts -> Maybe NormalSign

-- | Whether to use ANSI color codes in text output. Influenced by the
--   --color/colour flag (cf CliOptions), whether stdout is an interactive
--   terminal, and the value of TERM and existence of NO_COLOR environment
--   variables.
[color_] :: ReportOpts -> Bool
[transpose_] :: ReportOpts -> Bool
[layout_] :: ReportOpts -> Layout

-- | Should accounts be displayed: in the command's default style,
--   hierarchically, or as a flat list ?
data () => AccountListMode
ALFlat :: AccountListMode
ALTree :: AccountListMode

-- | How to accumulate calculated values across periods (columns) in a
--   balance report. "Balance report types -> Accumulation type" in the
--   hledger manual.
data () => BalanceAccumulation

-- | No accumulation. Eg, shows the change of balance in each period.
PerPeriod :: BalanceAccumulation

-- | Accumulate changes across periods, starting from zero at report start.
Cumulative :: BalanceAccumulation

-- | Accumulate changes across periods, including any from before report
--   start. Eg, shows the historical end balance of each period.
Historical :: BalanceAccumulation

-- | What to calculate for each cell in a balance report. "Balance report
--   types -> Calculation type" in the hledger manual.
data () => BalanceCalculation

-- | Sum of posting amounts in the period.
CalcChange :: BalanceCalculation

-- | Sum of posting amounts and the goal for the period.
CalcBudget :: BalanceCalculation

-- | Change from previous period's historical end value to this period's
--   historical end value.
CalcValueChange :: BalanceCalculation

-- | Change from previous period's gain, i.e. valuation minus cost basis.
CalcGain :: BalanceCalculation

-- | Number of postings in the period.
CalcPostingsCount :: BalanceCalculation

-- | Lenses for ReportOpts.
class () => HasReportOptsNoUpdate c
reportOptsNoUpdate :: HasReportOptsNoUpdate c => Lens' c ReportOpts
accountlistmode :: HasReportOptsNoUpdate c => Lens' c AccountListMode
average :: HasReportOptsNoUpdate c => Lens' c Bool
balanceaccum :: HasReportOptsNoUpdate c => Lens' c BalanceAccumulation
balancecalc :: HasReportOptsNoUpdate c => Lens' c BalanceCalculation
budgetpat :: HasReportOptsNoUpdate c => Lens' c (Maybe Text)
color__ :: HasReportOptsNoUpdate c => Lens' c Bool
conversionop :: HasReportOptsNoUpdate c => Lens' c (Maybe ConversionOp)
date2NoUpdate :: HasReportOptsNoUpdate c => Lens' c Bool
declared :: HasReportOptsNoUpdate c => Lens' c Bool
depthNoUpdate :: HasReportOptsNoUpdate c => Lens' c (Maybe Int)
drop__ :: HasReportOptsNoUpdate c => Lens' c Int
empty__ :: HasReportOptsNoUpdate c => Lens' c Bool
format :: HasReportOptsNoUpdate c => Lens' c StringFormat
infer_prices :: HasReportOptsNoUpdate c => Lens' c Bool
interval :: HasReportOptsNoUpdate c => Lens' c Interval
invert :: HasReportOptsNoUpdate c => Lens' c Bool
layout :: HasReportOptsNoUpdate c => Lens' c Layout
no_elide :: HasReportOptsNoUpdate c => Lens' c Bool
no_total :: HasReportOptsNoUpdate c => Lens' c Bool
normalbalance :: HasReportOptsNoUpdate c => Lens' c (Maybe NormalSign)
percent :: HasReportOptsNoUpdate c => Lens' c Bool
periodNoUpdate :: HasReportOptsNoUpdate c => Lens' c Period
pretty :: HasReportOptsNoUpdate c => Lens' c Bool
querystringNoUpdate :: HasReportOptsNoUpdate c => Lens' c [Text]
realNoUpdate :: HasReportOptsNoUpdate c => Lens' c Bool
related :: HasReportOptsNoUpdate c => Lens' c Bool
row_total :: HasReportOptsNoUpdate c => Lens' c Bool
show_costs :: HasReportOptsNoUpdate c => Lens' c Bool
sort_amount :: HasReportOptsNoUpdate c => Lens' c Bool
statusesNoUpdate :: HasReportOptsNoUpdate c => Lens' c [Status]
summary_only :: HasReportOptsNoUpdate c => Lens' c Bool
transpose__ :: HasReportOptsNoUpdate c => Lens' c Bool
txn_dates :: HasReportOptsNoUpdate c => Lens' c Bool
value :: HasReportOptsNoUpdate c => Lens' c (Maybe ValuationType)

-- | Special lenses for ReportOpts which also update the Query and
--   QueryOpts in ReportSpec. Note that these are not true lenses, as they
--   have a further restriction on the functor. This will work as a normal
--   lens for all common uses, but since they don't obey the lens laws for
--   some fancy cases, they may fail in some exotic circumstances.
--   
--   Note that setEither/overEither should only be necessary with
--   querystring and reportOpts: the other lenses should never fail.
--   
--   
Examples:
--   
--   
--   >>> import Lens.Micro (set)
--   
--   >>> _rsQuery <$> setEither querystring ["assets"] defreportspec
--   Right (Acct (RegexpCI "assets"))
--   
--   >>> _rsQuery <$> setEither querystring ["(assets"] defreportspec
--   Left "This regular expression is malformed, please correct it:\n(assets"
--   
--   >>> _rsQuery $ set querystring ["assets"] defreportspec
--   Acct (RegexpCI "assets")
--   
--   >>> _rsQuery $ set querystring ["(assets"] defreportspec
--   *** Exception: Error: Updating ReportSpec failed: try using overEither instead of over or setEither instead of set
--   
--   >>> _rsQuery $ set period (MonthPeriod 2021 08) defreportspec
--   Date DateSpan 2021-08
--   
class HasReportOptsNoUpdate a => HasReportOpts a
reportOpts :: HasReportOpts a => ReportableLens' a ReportOpts
period :: HasReportOpts a => ReportableLens' a Period
statuses :: HasReportOpts a => ReportableLens' a [Status]
depth :: HasReportOpts a => ReportableLens' a (Maybe Int)
date2 :: HasReportOpts a => ReportableLens' a Bool
real :: HasReportOpts a => ReportableLens' a Bool
querystring :: HasReportOpts a => ReportableLens' a [Text]
class () => HasReportSpec c
reportSpec :: HasReportSpec c => Lens' c ReportSpec
rsDay :: HasReportSpec c => Lens' c Day
rsQuery :: HasReportSpec c => Lens' c Query
rsQueryOpts :: HasReportSpec c => Lens' c [QueryOpt]
rsReportOpts :: HasReportSpec c => Lens' c ReportOpts

-- | A full name, display name, and depth for an account.
data () => DisplayName
DisplayName :: AccountName -> AccountName -> Int -> DisplayName
[displayFull] :: DisplayName -> AccountName
[displayName] :: DisplayName -> AccountName
[displayDepth] :: DisplayName -> Int

-- | Description of one subreport within a compound balance report. Part of
--   a CompoundBalanceCommandSpec, but also used in hledger-lib.
data () => CBCSubreportSpec a
CBCSubreportSpec :: Text -> Query -> (ReportOpts -> ReportOpts) -> (PeriodicReport DisplayName MixedAmount -> PeriodicReport a MixedAmount) -> Bool -> CBCSubreportSpec a

-- | The title to use for the subreport
[cbcsubreporttitle] :: CBCSubreportSpec a -> Text

-- | The Query to use for the subreport
[cbcsubreportquery] :: CBCSubreportSpec a -> Query

-- | A function to transform the ReportOpts used to produce the subreport
[cbcsubreportoptions] :: CBCSubreportSpec a -> ReportOpts -> ReportOpts

-- | A function to transform the result of the subreport
[cbcsubreporttransform] :: CBCSubreportSpec a -> PeriodicReport DisplayName MixedAmount -> PeriodicReport a MixedAmount

-- | Whether the subreport and overall report total are of the same sign
--   (e.g. Assets are normally positive in a balance sheet report, as is
--   the overall total. Liabilities are normally of the opposite sign.)
[cbcsubreportincreasestotal] :: CBCSubreportSpec a -> Bool

-- | A compound balance report has:
--   
--   
--   
- an overall title
--   
- the period (date span) of each column
--   
- one or more named, normal-positive multi balance reports, with
--   columns corresponding to the above, and a flag indicating whether they
--   increased or decreased the overall totals
--   
- a list of overall totals for each column, and their grand total
--   and average
--   
--   
--   It is used in compound balance report commands like balancesheet,
--   cashflow and incomestatement.
data () => CompoundPeriodicReport a b
CompoundPeriodicReport :: Text -> [DateSpan] -> [(Text, PeriodicReport a b, Bool)] -> PeriodicReportRow () b -> CompoundPeriodicReport a b
[cbrTitle] :: CompoundPeriodicReport a b -> Text
[cbrDates] :: CompoundPeriodicReport a b -> [DateSpan]
[cbrSubreports] :: CompoundPeriodicReport a b -> [(Text, PeriodicReport a b, Bool)]
[cbrTotals] :: CompoundPeriodicReport a b -> PeriodicReportRow () b
data () => PeriodicReportRow a b
PeriodicReportRow :: a -> [b] -> b -> b -> PeriodicReportRow a b
[prrName] :: PeriodicReportRow a b -> a
[prrAmounts] :: PeriodicReportRow a b -> [b]
[prrTotal] :: PeriodicReportRow a b -> b
[prrAverage] :: PeriodicReportRow a b -> b

-- | A periodic report is a generic tabular report, where each row
--   corresponds to some label (usually an account name) and each column to
--   a date period. The column periods are usually consecutive subperiods
--   formed by splitting the overall report period by some report interval
--   (daily, weekly, etc.). It has:
--   
--   
--   
- a list of each column's period (date span)
--   
- a list of rows, each containing:
--   
--   
--   
--   
- an account label
--   
- the account's depth
--   
- A list of amounts, one for each column. Depending on the value
--   type, these can represent balance changes, ending balances, budget
--   performance, etc. (for example, see BalanceAccumulation and
--   Hledger.Cli.Commands.Balance).
--   
- the total of the row's amounts for a periodic report, or zero for
--   cumulative/historical reports (since summing end balances generally
--   doesn't make sense).
--   
- the average of the row's amounts
--   
--   
--   
--   
- the column totals, and the overall grand total (or zero for
--   cumulative/historical reports) and grand average.
--   
data () => PeriodicReport a b
PeriodicReport :: [DateSpan] -> [PeriodicReportRow a b] -> PeriodicReportRow () b -> PeriodicReport a b
[prDates] :: PeriodicReport a b -> [DateSpan]
[prRows] :: PeriodicReport a b -> [PeriodicReportRow a b]
[prTotals] :: PeriodicReport a b -> PeriodicReportRow () b
type Average = MixedAmount
type Total = MixedAmount
type Balance = MixedAmount
type Percentage = Decimal
type PostingsReportItem = (Maybe Day, Maybe Period, Maybe Text, Posting, MixedAmount)

-- | A postings report is a list of postings with a running total, and a
--   little extra transaction info to help with rendering. This is used eg
--   for the register command.
type PostingsReport = [PostingsReportItem]
type MultiBalanceReportRow = PeriodicReportRow DisplayName MixedAmount

-- | A multi balance report is a kind of periodic report, where the amounts
--   correspond to balance changes or ending balances in a given period. It
--   has:
--   
--   
--   
- a list of each column's period (date span)
--   
- a list of rows, each containing:
--   
--   
--   
--   
- the full account name, display name, and display depth
--   
- A list of amounts, one for each column.
--   
- the total of the row's amounts for a periodic report
--   
- the average of the row's amounts
--   
--   
--   
--   
- the column totals, and the overall grand total (or zero for
--   cumulative/historical reports) and grand average.
--   
type MultiBalanceReport = PeriodicReport DisplayName MixedAmount
type EntriesReportItem = Transaction

-- | A journal entries report is a list of whole transactions as originally
--   entered in the journal (mostly). This is used by eg hledger's print
--   command and hledger-web's journal entries view.
type EntriesReport = [EntriesReportItem]
type BudgetReport = PeriodicReport DisplayName BudgetCell
type BudgetReportRow = PeriodicReportRow DisplayName BudgetCell

-- | A budget report tracks expected and actual changes per account and
--   subperiod.
type BudgetCell = (Maybe Change, Maybe BudgetGoal)
type BudgetAverage = Average
type BudgetTotal = Total
type BudgetGoal = Change
type BalanceReportItem = (AccountName, AccountName, Int, MixedAmount)

-- | A simple balance report. It has:
--   
--   
--   
- a list of items, one per account, each containing:
--   
--   
--   
--   
- the full account name
--   
- the Ledger-style elided short account name (the leaf account name,
--   prefixed by any boring parents immediately above); or with --flat, the
--   full account name again
--   
- the number of indentation steps for rendering a Ledger-style
--   account tree, taking into account elided boring parents, --no-elide
--   and --flat
--   
- an amount
--   
--   
--   
--   
- the total of all amounts
--   
type BalanceReport = ([BalanceReportItem], MixedAmount)
type AccountTransactionsReportItem = (Transaction, Transaction, Bool, Text, MixedAmount, MixedAmount)

-- | An account transactions report represents transactions affecting a
--   particular account (or possibly several accounts, but we don't use
--   that). It is used eg by hledger-ui's and hledger-web's register view,
--   and hledger's aregister report, where we want to show one row per
--   transaction, in the context of the current account. Report items
--   consist of:
--   
--   
--   
- the transaction, unmodified
--   
- the transaction as seen in the context of the current account and
--   query, which means:
--   
- the transaction date is set to the "transaction context date": the
--   earliest of the transaction date and any other posting dates of
--   postings to the current account (matched by the report query).
--   
- the transaction's postings are filtered, excluding any which are
--   not matched by the report query
--   
- a text description of the other account(s) posted to/from
--   
- a flag indicating whether there's more than one other account
--   involved
--   
- the total increase/decrease to the current account
--   
- the report transactions' running total after this transaction; or
--   if historical balance is requested (-H), the historical running total.
--   The historical running total includes transactions from before the
--   report start date if one is specified, filtered by the report query.
--   The historical running total may or may not be the account's
--   historical running balance, depending on the report query.
--   
--   
--   Items are sorted by transaction register date (the earliest date the
--   transaction posts to the current account), most recent first.
--   Reporting intervals are currently ignored.
type AccountTransactionsReport = [AccountTransactionsReportItem]

-- | A file path optionally prefixed by a reader name and colon (journal:,
--   csv:, timedot:, etc.).
type PrefixedFilePath = FilePath
type Assertion = IO ()
type AssertionPredicate = IO Bool
class () => Assertable t
assert :: Assertable t => t -> Assertion
data () => HUnitFailure
HUnitFailure :: Maybe SrcLoc -> String -> HUnitFailure
class () => AssertionPredicable t
assertionPredicate :: AssertionPredicable t => t -> IO Bool
data () => CalendarDiffDays
CalendarDiffDays :: Integer -> Integer -> CalendarDiffDays
[cdMonths] :: CalendarDiffDays -> Integer
[cdDays] :: CalendarDiffDays -> Integer

-- | Month of year, in range 1 (January) to 12 (December).
type MonthOfYear = Int
data () => DayOfWeek
Monday :: DayOfWeek
Tuesday :: DayOfWeek
Wednesday :: DayOfWeek
Thursday :: DayOfWeek
Friday :: DayOfWeek
Saturday :: DayOfWeek
Sunday :: DayOfWeek

-- | This is a length of time, as measured by a clock. Conversion functions
--   such as fromInteger and realToFrac will treat it as
--   seconds. For example, (0.010 :: DiffTime) corresponds to 10
--   milliseconds.
--   
--   It has a precision of one picosecond (= 10^-12 s). Enumeration
--   functions will treat it as picoseconds.
data () => DiffTime

-- | This is a length of time, as measured by UTC. It has a precision of
--   10^-12 s.
--   
--   Conversion functions such as fromInteger and realToFrac
--   will treat it as seconds. For example, (0.010 ::
--   NominalDiffTime) corresponds to 10 milliseconds.
--   
--   It has a precision of one picosecond (= 10^-12 s). Enumeration
--   functions will treat it as picoseconds.
--   
--   It ignores leap-seconds, so it's not necessarily a fixed amount of
--   clock time. For instance, 23:00 UTC + 2 hours of NominalDiffTime =
--   01:00 UTC (+ 1 day), regardless of whether a leap-second intervened.
data () => NominalDiffTime

-- | The Modified Julian Date is the day with the fraction of the day,
--   measured from UT midnight. It's used to represent UT1, which is time
--   as measured by the earth's rotation, adjusted for various wobbles.
newtype () => UniversalTime
ModJulianDate :: Rational -> UniversalTime
[getModJulianDate] :: UniversalTime -> Rational
data () => CalendarDiffTime
CalendarDiffTime :: Integer -> NominalDiffTime -> CalendarDiffTime
[ctMonths] :: CalendarDiffTime -> Integer
[ctTime] :: CalendarDiffTime -> NominalDiffTime

-- | A TimeZone is a whole number of minutes offset from UTC, together with
--   a name and a "just for summer" flag.
data () => TimeZone
TimeZone :: Int -> Bool -> String -> TimeZone

-- | The number of minutes offset from UTC. Positive means local time will
--   be later in the day than UTC.
[timeZoneMinutes] :: TimeZone -> Int

-- | Is this time zone just persisting for the summer?
[timeZoneSummerOnly] :: TimeZone -> Bool

-- | The name of the zone, typically a three- or four-letter acronym.
[timeZoneName] :: TimeZone -> String

-- | Time of day as represented in hour, minute and second (with
--   picoseconds), typically used to express local time of day.
--   
--   TimeOfDay 24 0 0 is considered invalid for the purposes of
--   makeTimeOfDayValid, as well as reading and parsing, but valid
--   for ISO 8601 parsing in Data.Time.Format.ISO8601.
data () => TimeOfDay
TimeOfDay :: Int -> Int -> Pico -> TimeOfDay

-- | range 0 - 23
[todHour] :: TimeOfDay -> Int

-- | range 0 - 59
[todMin] :: TimeOfDay -> Int

-- | Note that 0 <= todSec < 61, accomodating leap seconds.
--   Any local minute may have a leap second, since leap seconds happen in
--   all zones simultaneously
[todSec] :: TimeOfDay -> Pico

-- | A simple day and time aggregate, where the day is of the specified
--   parameter, and the time is a TimeOfDay. Conversion of this (as local
--   civil time) to UTC depends on the time zone. Conversion of this (as
--   local mean time) to UT1 depends on the longitude.
data () => LocalTime
LocalTime :: Day -> TimeOfDay -> LocalTime
[localDay] :: LocalTime -> Day
[localTimeOfDay] :: LocalTime -> TimeOfDay
data () => TimeLocale
TimeLocale :: [(String, String)] -> [(String, String)] -> (String, String) -> String -> String -> String -> String -> [TimeZone] -> TimeLocale

-- | full and abbreviated week days, starting with Sunday
[wDays] :: TimeLocale -> [(String, String)]

-- | full and abbreviated months
[months] :: TimeLocale -> [(String, String)]

-- | AM/PM symbols
[amPm] :: TimeLocale -> (String, String)

-- | formatting strings
[dateTimeFmt] :: TimeLocale -> String

-- | formatting strings
[dateFmt] :: TimeLocale -> String

-- | formatting strings
[timeFmt] :: TimeLocale -> String

-- | formatting strings
[time12Fmt] :: TimeLocale -> String

-- | time zones known by name
[knownTimeZones] :: TimeLocale -> [TimeZone]

-- | The class of types which can be parsed given a UNIX-style time format
--   string.
class () => ParseTime t
class () => FormatTime t

-- | A local time together with a time zone.
--   
--   There is no Eq instance for ZonedTime. If you want to
--   compare local times, use zonedTimeToLocalTime. If you want to
--   compare absolute times, use zonedTimeToUTC.
data () => ZonedTime
ZonedTime :: LocalTime -> TimeZone -> ZonedTime
[zonedTimeToLocalTime] :: ZonedTime -> LocalTime
[zonedTimeZone] :: ZonedTime -> TimeZone

-- | Command line options, used in the hledger package and above.
--   This is the "opts" used throughout hledger CLI code. representing the
--   options and arguments that were provided at startup on the
--   command-line.
data CliOpts
CliOpts :: RawOpts -> String -> [FilePath] -> InputOpts -> ReportSpec -> Maybe FilePath -> Maybe String -> Int -> Bool -> Maybe String -> Int -> POSIXTime -> CliOpts
[rawopts_] :: CliOpts -> RawOpts
[command_] :: CliOpts -> String
[file_] :: CliOpts -> [FilePath]
[inputopts_] :: CliOpts -> InputOpts
[reportspec_] :: CliOpts -> ReportSpec
[output_file_] :: CliOpts -> Maybe FilePath
[output_format_] :: CliOpts -> Maybe String

-- | debug level, set by --debug[=N]. See also debugLevel.
[debug_] :: CliOpts -> Int
[no_new_accounts_] :: CliOpts -> Bool

-- | the --width value provided, if any
[width_] :: CliOpts -> Maybe String

-- | estimated usable screen width, based on 1. the COLUMNS env var, if set
--   2. the width reported by the terminal, if supported 3. the default
--   (80)
[available_width_] :: CliOpts -> Int
[progstarttime_] :: CliOpts -> POSIXTime
class HasCliOpts c_ahMj
cliOpts :: HasCliOpts c_ahMj => Lens' c_ahMj CliOpts
available_width :: HasCliOpts c_ahMj => Lens' c_ahMj Int
command :: HasCliOpts c_ahMj => Lens' c_ahMj String
debug__ :: HasCliOpts c_ahMj => Lens' c_ahMj Int
file__ :: HasCliOpts c_ahMj => Lens' c_ahMj [FilePath]
inputopts :: HasCliOpts c_ahMj => Lens' c_ahMj InputOpts
no_new_accounts :: HasCliOpts c_ahMj => Lens' c_ahMj Bool
output_file :: HasCliOpts c_ahMj => Lens' c_ahMj (Maybe FilePath)
output_format :: HasCliOpts c_ahMj => Lens' c_ahMj (Maybe String)
progstarttime :: HasCliOpts c_ahMj => Lens' c_ahMj POSIXTime
rawopts__ :: HasCliOpts c_ahMj => Lens' c_ahMj RawOpts
reportspec :: HasCliOpts c_ahMj => Lens' c_ahMj ReportSpec
width__ :: HasCliOpts c_ahMj => Lens' c_ahMj (Maybe String)

-- | A command's documentation. Used both as part of CLI help, and as part
--   of the hledger manual. See parseCommandDoc.
type CommandDoc = String

-- | Description of a compound balance report command, from which we
--   generate the command's cmdargs mode and IO action. A compound balance
--   report command shows one or more sections/subreports, each with its
--   own title and subtotals row, in a certain order, plus a grand totals
--   row if there's more than one section. Examples are the balancesheet,
--   cashflow and incomestatement commands.
--   
--   Compound balance reports do sign normalisation: they show all account
--   balances as normally positive, unlike the ordinary BalanceReport and
--   most hledger commands which show incomeliabilityequity balances
--   as normally negative. Each subreport specifies the normal sign of its
--   amounts, and whether it should be added to or subtracted from the
--   grand total.
data CompoundBalanceCommandSpec
CompoundBalanceCommandSpec :: CommandDoc -> String -> [CBCSubreportSpec DisplayName] -> BalanceAccumulation -> CompoundBalanceCommandSpec

-- | the command's name(s) and documentation
[cbcdoc] :: CompoundBalanceCommandSpec -> CommandDoc

-- | overall report title
[cbctitle] :: CompoundBalanceCommandSpec -> String

-- | subreport details
[cbcqueries] :: CompoundBalanceCommandSpec -> [CBCSubreportSpec DisplayName]

-- | how to accumulate balances (per-period, cumulative, historical)
--   (overrides command line flags)
[cbcaccum] :: CompoundBalanceCommandSpec -> BalanceAccumulation
type Topic = String
type ProgramName = String
type PackageVersion = String
type VersionString = String
pattern MixedAmountKeyNoPrice :: () => !CommoditySymbol -> MixedAmountKey
pattern MixedAmountKeyTotalPrice :: () => !CommoditySymbol -> !CommoditySymbol -> MixedAmountKey
pattern MixedAmountKeyUnitPrice :: () => !CommoditySymbol -> !CommoditySymbol -> !Quantity -> MixedAmountKey

-- | The twelve MonthOfYear patterns form a COMPLETE set.
pattern December :: MonthOfYear
pattern November :: MonthOfYear
pattern October :: MonthOfYear
pattern September :: MonthOfYear
pattern August :: MonthOfYear
pattern July :: MonthOfYear
pattern June :: MonthOfYear
pattern May :: MonthOfYear
pattern April :: MonthOfYear
pattern March :: MonthOfYear
pattern February :: MonthOfYear
pattern January :: MonthOfYear

-- | Also known as Before Christ. Note that Year 1 = 1 CE, and the previous
--   Year 0 = 1 BCE. CommonEra and BeforeCommonEra form a
--   COMPLETE set.
pattern BeforeCommonEra :: Integer -> Year

-- | Also known as Anno Domini.
pattern CommonEra :: Integer -> Year

-- | Bidirectional abstract constructor for the proleptic Gregorian
--   calendar. Invalid values will be clipped to the correct range, month
--   first, then day.
pattern YearMonthDay :: Year -> MonthOfYear -> DayOfMonth -> Day

-- | Display the given text on the terminal, using the user's $PAGER if the
--   text is taller than the current terminal and stdout is interactive and
--   TERM is not "dumb" (except on Windows, where a pager will not be
--   used). If the text contains ANSI codes, because hledger thinks the
--   current terminal supports those, the pager should be configured to
--   display those, otherwise users will see junk on screen (#2015). We
--   call "setLessR" at hledger startup to make that less likely.
pager :: String -> IO ()

-- | Process a list of flags (usually obtained from
--   getArgs/expandArgsAt) with a mode. Returns
--   Left and an error message if the command line fails to parse,
--   or Right and the associated value.
process :: Mode a -> [String] -> Either String a

-- | Convert a letter to the corresponding upper-case letter, if any. Any
--   other character is returned unchanged.
toUpper :: Char -> Char

-- | Test whether the structure is empty. The default implementation is
--   Left-associative and lazy in both the initial element and the
--   accumulator. Thus optimised for structures where the first element can
--   be accessed in constant time. Structures where this is not the case
--   should have a non-default implementation.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> null []
--   True
--   
--   
--   
--   >>> null [1]
--   False
--   
--   
--   null is expected to terminate even for infinite structures. The
--   default implementation terminates provided the structure is bounded on
--   the left (there is a leftmost element).
--   
--   
--   >>> null [1..]
--   False
--   
null :: Foldable t => t a -> Bool

-- | Right-associative fold of a structure, lazy in the accumulator.
--   
--   In the case of lists, foldr, when applied to a binary operator,
--   a starting value (typically the right-identity of the operator), and a
--   list, reduces the list using the binary operator, from right to left:
--   
--   
--   foldr f z [x1, x2, ..., xn] == x1 `f` (x2 `f` ... (xn `f` z)...)
--   
--   
--   Note that since the head of the resulting expression is produced by an
--   application of the operator to the first element of the list, given an
--   operator lazy in its right argument, foldr can produce a
--   terminating expression from an unbounded list.
--   
--   For a general Foldable structure this should be semantically
--   identical to,
--   
--   
--   foldr f z = foldr f z . toList
--   
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> foldr (||) False [False, True, False]
--   True
--   
--   
--   
--   >>> foldr (||) False []
--   False
--   
--   
--   
--   >>> foldr (\c acc -> acc ++ [c]) "foo" ['a', 'b', 'c', 'd']
--   "foodcba"
--   
--   
--   
Infinite structures
--   
--   ⚠️ Applying foldr to infinite structures usually doesn't
--   terminate.
--   
--   It may still terminate under one of the following conditions:
--   
--   
--   
- the folding function is short-circuiting
--   
- the folding function is lazy on its second argument
--   
--   
--   
Short-circuiting
--   
--   (||) short-circuits on True values, so the
--   following terminates because there is a True value finitely far
--   from the left side:
--   
--   
--   >>> foldr (||) False (True : repeat False)
--   True
--   
--   
--   But the following doesn't terminate:
--   
--   
--   >>> foldr (||) False (repeat False ++ [True])
--   * Hangs forever *
--   
--   
--   
Laziness in the second argument
--   
--   Applying foldr to infinite structures terminates when the
--   operator is lazy in its second argument (the initial accumulator is
--   never used in this case, and so could be left undefined, but
--   [] is more clear):
--   
--   
--   >>> take 5 $ foldr (\i acc -> i : fmap (+3) acc) [] (repeat 1)
--   [1,4,7,10,13]
--   
foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b

-- | Left-associative fold of a structure, lazy in the accumulator. This is
--   rarely what you want, but can work well for structures with efficient
--   right-to-left sequencing and an operator that is lazy in its left
--   argument.
--   
--   In the case of lists, foldl, when applied to a binary operator,
--   a starting value (typically the left-identity of the operator), and a
--   list, reduces the list using the binary operator, from left to right:
--   
--   
--   foldl f z [x1, x2, ..., xn] == (...((z `f` x1) `f` x2) `f`...) `f` xn
--   
--   
--   Note that to produce the outermost application of the operator the
--   entire input list must be traversed. Like all left-associative folds,
--   foldl will diverge if given an infinite list.
--   
--   If you want an efficient strict left-fold, you probably want to use
--   foldl' instead of foldl. The reason for this is that the
--   latter does not force the inner results (e.g. z `f` x1
--   in the above example) before applying them to the operator (e.g. to
--   (`f` x2)). This results in a thunk chain O(n) elements
--   long, which then must be evaluated from the outside-in.
--   
--   For a general Foldable structure this should be semantically
--   identical to:
--   
--   
--   foldl f z = foldl f z . toList
--   
--   
--   
Examples
--   
--   The first example is a strict fold, which in practice is best
--   performed with foldl'.
--   
--   
--   >>> foldl (+) 42 [1,2,3,4]
--   52
--   
--   
--   Though the result below is lazy, the input is reversed before
--   prepending it to the initial accumulator, so corecursion begins only
--   after traversing the entire input string.
--   
--   
--   >>> foldl (\acc c -> c : acc) "abcd" "efgh"
--   "hgfeabcd"
--   
--   
--   A left fold of a structure that is infinite on the right cannot
--   terminate, even when for any finite input the fold just returns the
--   initial accumulator:
--   
--   
--   >>> foldl (\a _ -> a) 0 $ repeat 1
--   * Hangs forever *
--   
--   
--   WARNING: When it comes to lists, you always want to use either
--   foldl' or foldr instead.
foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b

-- | Left-associative fold of a structure but with strict application of
--   the operator.
--   
--   This ensures that each step of the fold is forced to Weak Head Normal
--   Form before being applied, avoiding the collection of thunks that
--   would otherwise occur. This is often what you want to strictly reduce
--   a finite structure to a single strict result (e.g. sum).
--   
--   For a general Foldable structure this should be semantically
--   identical to,
--   
--   
--   foldl' f z = foldl' f z . toList
--   
foldl' :: Foldable t => (b -> a -> b) -> b -> t a -> b

-- | Returns the size/length of a finite structure as an Int. The
--   default implementation just counts elements starting with the
--   leftmost. Instances for structures that can compute the element count
--   faster than via element-by-element counting, should provide a
--   specialised implementation.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> length []
--   0
--   
--   
--   
--   >>> length ['a', 'b', 'c']
--   3
--   
--   >>> length [1..]
--   * Hangs forever *
--   
length :: Foldable t => t a -> Int

-- | A variant of foldl that has no base case, and thus may only be
--   applied to non-empty structures.
--   
--   This function is non-total and will raise a runtime exception if the
--   structure happens to be empty.
--   
--   
--   foldl1 f = foldl1 f . toList
--   
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> foldl1 (+) [1..4]
--   10
--   
--   
--   
--   >>> foldl1 (+) []
--   *** Exception: Prelude.foldl1: empty list
--   
--   
--   
--   >>> foldl1 (+) Nothing
--   *** Exception: foldl1: empty structure
--   
--   
--   
--   >>> foldl1 (-) [1..4]
--   -8
--   
--   
--   
--   >>> foldl1 (&&) [True, False, True, True]
--   False
--   
--   
--   
--   >>> foldl1 (||) [False, False, True, True]
--   True
--   
--   
--   
--   >>> foldl1 (+) [1..]
--   * Hangs forever *
--   
foldl1 :: Foldable t => (a -> a -> a) -> t a -> a

-- | The sum function computes the sum of the numbers of a
--   structure.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> sum []
--   0
--   
--   
--   
--   >>> sum [42]
--   42
--   
--   
--   
--   >>> sum [1..10]
--   55
--   
--   
--   
--   >>> sum [4.1, 2.0, 1.7]
--   7.8
--   
--   
--   
--   >>> sum [1..]
--   * Hangs forever *
--   
sum :: (Foldable t, Num a) => t a -> a

-- | The product function computes the product of the numbers of a
--   structure.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> product []
--   1
--   
--   
--   
--   >>> product [42]
--   42
--   
--   
--   
--   >>> product [1..10]
--   3628800
--   
--   
--   
--   >>> product [4.1, 2.0, 1.7]
--   13.939999999999998
--   
--   
--   
--   >>> product [1..]
--   * Hangs forever *
--   
product :: (Foldable t, Num a) => t a -> a

-- | A variant of foldr that has no base case, and thus may only be
--   applied to non-empty structures.
--   
--   This function is non-total and will raise a runtime exception if the
--   structure happens to be empty.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> foldr1 (+) [1..4]
--   10
--   
--   
--   
--   >>> foldr1 (+) []
--   Exception: Prelude.foldr1: empty list
--   
--   
--   
--   >>> foldr1 (+) Nothing
--   *** Exception: foldr1: empty structure
--   
--   
--   
--   >>> foldr1 (-) [1..4]
--   -2
--   
--   
--   
--   >>> foldr1 (&&) [True, False, True, True]
--   False
--   
--   
--   
--   >>> foldr1 (||) [False, False, True, True]
--   True
--   
--   
--   
--   >>> foldr1 (+) [1..]
--   * Hangs forever *
--   
foldr1 :: Foldable t => (a -> a -> a) -> t a -> a

-- | The largest element of a non-empty structure.
--   
--   This function is non-total and will raise a runtime exception if the
--   structure happens to be empty. A structure that supports random access
--   and maintains its elements in order should provide a specialised
--   implementation to return the maximum in faster than linear time.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> maximum [1..10]
--   10
--   
--   
--   
--   >>> maximum []
--   *** Exception: Prelude.maximum: empty list
--   
--   
--   
--   >>> maximum Nothing
--   *** Exception: maximum: empty structure
--   
--   
--   WARNING: This function is partial for possibly-empty structures like
--   lists.
maximum :: (Foldable t, Ord a) => t a -> a

-- | The least element of a non-empty structure.
--   
--   This function is non-total and will raise a runtime exception if the
--   structure happens to be empty. A structure that supports random access
--   and maintains its elements in order should provide a specialised
--   implementation to return the minimum in faster than linear time.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> minimum [1..10]
--   1
--   
--   
--   
--   >>> minimum []
--   *** Exception: Prelude.minimum: empty list
--   
--   
--   
--   >>> minimum Nothing
--   *** Exception: minimum: empty structure
--   
--   
--   WARNING: This function is partial for possibly-empty structures like
--   lists.
minimum :: (Foldable t, Ord a) => t a -> a

-- | Does the element occur in the structure?
--   
--   Note: elem is often used in infix form.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> 3 `elem` []
--   False
--   
--   
--   
--   >>> 3 `elem` [1,2]
--   False
--   
--   
--   
--   >>> 3 `elem` [1,2,3,4,5]
--   True
--   
--   
--   For infinite structures, the default implementation of elem
--   terminates if the sought-after value exists at a finite distance from
--   the left side of the structure:
--   
--   
--   >>> 3 `elem` [1..]
--   True
--   
--   
--   
--   >>> 3 `elem` ([4..] ++ [3])
--   * Hangs forever *
--   
elem :: (Foldable t, Eq a) => a -> t a -> Bool
infix 4 `elem`

-- | Produce singleton list.
--   
--   
--   >>> singleton True
--   [True]
--   
singleton :: a -> [a]

-- | <math>. delete x removes the first occurrence of
--   x from its list argument. For example,
--   
--   
--   >>> delete 'a' "banana"
--   "bnana"
--   
--   
--   It is a special case of deleteBy, which allows the programmer
--   to supply their own equality test.
delete :: Eq a => a -> [a] -> [a]

-- | <math>. lookup key assocs looks up a key in an
--   association list. For the result to be Nothing, the list must
--   be finite.
--   
--   
--   >>> lookup 2 []
--   Nothing
--   
--   >>> lookup 2 [(1, "first")]
--   Nothing
--   
--   >>> lookup 2 [(1, "first"), (2, "second"), (3, "third")]
--   Just "second"
--   
lookup :: Eq a => a -> [(a, b)] -> Maybe b

-- | <math>. The insert function takes an element and a list
--   and inserts the element into the list at the first position where it
--   is less than or equal to the next element. In particular, if the list
--   is sorted before the call, the result will also be sorted. It is a
--   special case of insertBy, which allows the programmer to supply
--   their own comparison function.
--   
--   
--   >>> insert 4 [1,2,3,5,6,7]
--   [1,2,3,4,5,6,7]
--   
insert :: Ord a => a -> [a] -> [a]

-- | <math>. map f xs is the list obtained by
--   applying f to each element of xs, i.e.,
--   
--   
--   map f [x1, x2, ..., xn] == [f x1, f x2, ..., f xn]
--   map f [x1, x2, ...] == [f x1, f x2, ...]
--   
--   
--   
--   >>> map (+1) [1, 2, 3]
--   [2,3,4]
--   
map :: (a -> b) -> [a] -> [b]

-- | The union function returns the list union of the two lists. It
--   is a special case of unionBy, which allows the programmer to
--   supply their own equality test. For example,
--   
--   
--   >>> "dog" `union` "cow"
--   "dogcw"
--   
--   
--   If equal elements are present in both lists, an element from the first
--   list will be used. If the second list contains equal elements, only
--   the first one will be retained:
--   
--   
--   >>> import Data.Semigroup
--   
--   >>> union [Arg () "dog"] [Arg () "cow"]
--   [Arg () "dog"]
--   
--   >>> union [] [Arg () "dog", Arg () "cow"]
--   [Arg () "dog"]
--   
--   
--   However if the first list contains duplicates, so will the result:
--   
--   
--   >>> "coot" `union` "duck"
--   "cootduk"
--   
--   >>> "duck" `union` "coot"
--   "duckot"
--   
--   
--   union is productive even if both arguments are infinite.
union :: Eq a => [a] -> [a] -> [a]

-- | <math>. filter, applied to a predicate and a list,
--   returns the list of those elements that satisfy the predicate; i.e.,
--   
--   
--   filter p xs = [ x | x <- xs, p x]
--   
--   
--   
--   >>> filter odd [1, 2, 3]
--   [1,3]
--   
filter :: (a -> Bool) -> [a] -> [a]

-- | The mapMaybe function is a version of map which can
--   throw out elements. In particular, the functional argument returns
--   something of type Maybe b. If this is Nothing,
--   no element is added on to the result list. If it is Just
--   b, then b is included in the result list.
--   
--   
Examples
--   
--   Using mapMaybe f x is a shortcut for
--   catMaybes $ map f x in most cases:
--   
--   
--   >>> import Text.Read ( readMaybe )
--   
--   >>> let readMaybeInt = readMaybe :: String -> Maybe Int
--   
--   >>> mapMaybe readMaybeInt ["1", "Foo", "3"]
--   [1,3]
--   
--   >>> catMaybes $ map readMaybeInt ["1", "Foo", "3"]
--   [1,3]
--   
--   
--   If we map the Just constructor, the entire list should be
--   returned:
--   
--   
--   >>> mapMaybe Just [1,2,3]
--   [1,2,3]
--   
mapMaybe :: (a -> Maybe b) -> [a] -> [b]

-- | Convert a letter to the corresponding lower-case letter, if any. Any
--   other character is returned unchanged.
toLower :: Char -> Char

-- | Append two lists, i.e.,
--   
--   
--   [x1, ..., xm] ++ [y1, ..., yn] == [x1, ..., xm, y1, ..., yn]
--   [x1, ..., xm] ++ [y1, ...] == [x1, ..., xm, y1, ...]
--   
--   
--   If the first list is not finite, the result is the first list.
--   
--   WARNING: This function takes linear time in the number of elements of
--   the first list.
(++) :: [a] -> [a] -> [a]
infixr 5 ++

-- | An infix synonym for fmap.
--   
--   The name of this operator is an allusion to $. Note the
--   similarities between their types:
--   
--   
--    ($)  ::              (a -> b) ->   a ->   b
--   (<$>) :: Functor f => (a -> b) -> f a -> f b
--   
--   
--   Whereas $ is function application, <$> is function
--   application lifted over a Functor.
--   
--   
Examples
--   
--   Convert from a Maybe Int to a Maybe
--   String using show:
--   
--   
--   >>> show <$> Nothing
--   Nothing
--   
--   >>> show <$> Just 3
--   Just "3"
--   
--   
--   Convert from an Either Int Int to an
--   Either Int String using show:
--   
--   
--   >>> show <$> Left 17
--   Left 17
--   
--   >>> show <$> Right 17
--   Right "17"
--   
--   
--   Double each element of a list:
--   
--   
--   >>> (*2) <$> [1,2,3]
--   [2,4,6]
--   
--   
--   Apply even to the second element of a pair:
--   
--   
--   >>> even <$> (2,2)
--   (2,True)
--   
(<$>) :: Functor f => (a -> b) -> f a -> f b
infixl 4 <$>

-- | The join function is the conventional monad join operator. It
--   is used to remove one level of monadic structure, projecting its bound
--   argument into the outer level.
--   
--   'join bss' can be understood as the do
--   expression
--   
--   
--   do bs <- bss
--      bs
--   
--   
--   
Examples
--   
--   A common use of join is to run an IO computation
--   returned from an STM transaction, since STM transactions
--   can't perform IO directly. Recall that
--   
--   
--   atomically :: STM a -> IO a
--   
--   
--   is used to run STM transactions atomically. So, by specializing
--   the types of atomically and join to
--   
--   
--   atomically :: STM (IO b) -> IO (IO b)
--   join       :: IO (IO b)  -> IO b
--   
--   
--   we can compose them as
--   
--   
--   join . atomically :: STM (IO b) -> IO b
--   
--   
--   to run an STM transaction and the IO action it returns.
join :: Monad m => m (m a) -> m a

-- | Is the handle connected to a terminal?
--   
--   On Windows the result of hIsTerminalDevide might be
--   misleading, because non-native terminals, such as MinTTY used in MSYS
--   and Cygwin environments, are implemented via redirection. Use
--   System.Win32.Types.withHandleToHANDLE
--   System.Win32.MinTTY.isMinTTYHandle to recognise it. Also consider
--   ansi-terminal package for crossplatform terminal support.
hIsTerminalDevice :: Handle -> IO Bool
stdout :: Handle
stdin :: Handle

-- | <math>. zipWith generalises zip by zipping with
--   the function given as the first argument, instead of a tupling
--   function.
--   
--   
--   zipWith (,) xs ys == zip xs ys
--   zipWith f [x1,x2,x3..] [y1,y2,y3..] == [f x1 y1, f x2 y2, f x3 y3..]
--   
--   
--   For example, zipWith (+) is applied to two lists to
--   produce the list of corresponding sums:
--   
--   
--   >>> zipWith (+) [1, 2, 3] [4, 5, 6]
--   [5,7,9]
--   
--   
--   zipWith is right-lazy:
--   
--   
--   >>> let f = undefined
--   
--   >>> zipWith f [] undefined
--   []
--   
--   
--   zipWith is capable of list fusion, but it is restricted to its
--   first list argument and its resulting list.
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]

-- | Computation hGetContents hdl returns the list of
--   characters corresponding to the unread portion of the channel or file
--   managed by hdl, which is put into an intermediate state,
--   semi-closed. In this state, hdl is effectively closed,
--   but items are read from hdl on demand and accumulated in a
--   special list returned by hGetContents hdl.
--   
--   Any operation that fails because a handle is closed, also fails if a
--   handle is semi-closed. The only exception is hClose. A
--   semi-closed handle becomes closed:
--   
--   
--   
- if hClose is applied to it;
--   
- if an I/O error occurs when reading an item from the handle;
--   
- or once the entire contents of the handle has been read.
--   
--   
--   Once a semi-closed handle becomes closed, the contents of the
--   associated list becomes fixed. The contents of this final list is only
--   partially specified: it will contain at least all the items of the
--   stream that were evaluated prior to the handle becoming closed.
--   
--   Any I/O errors encountered while a handle is semi-closed are simply
--   discarded.
--   
--   This operation may fail with:
--   
--   
--   
- isEOFError if the end of file has been reached.
--   
hGetContents :: Handle -> IO String

-- | The sortBy function is the non-overloaded version of
--   sort. The argument must be finite.
--   
--   
--   >>> sortBy (\(a,_) (b,_) -> compare a b) [(2, "world"), (4, "!"), (1, "Hello")]
--   [(1,"Hello"),(2,"world"),(4,"!")]
--   
--   
--   The supplied comparison relation is supposed to be reflexive and
--   antisymmetric, otherwise, e. g., for _ _ -> GT, the
--   ordered list simply does not exist. The relation is also expected to
--   be transitive: if it is not then sortBy might fail to find an
--   ordered permutation, even if it exists.
sortBy :: (a -> a -> Ordering) -> [a] -> [a]

-- | <math>. The genericLength function is an overloaded
--   version of length. In particular, instead of returning an
--   Int, it returns any type which is an instance of Num. It
--   is, however, less efficient than length.
--   
--   
--   >>> genericLength [1, 2, 3] :: Int
--   3
--   
--   >>> genericLength [1, 2, 3] :: Float
--   3.0
--   
--   
--   Users should take care to pick a return type that is wide enough to
--   contain the full length of the list. If the width is insufficient, the
--   overflow behaviour will depend on the (+) implementation in
--   the selected Num instance. The following example overflows
--   because the actual list length of 200 lies outside of the
--   Int8 range of -128..127.
--   
--   
--   >>> genericLength [1..200] :: Int8
--   -56
--   
genericLength :: Num i => [a] -> i

-- | The largest element of a non-empty structure with respect to the given
--   comparison function.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> maximumBy (compare `on` length) ["Hello", "World", "!", "Longest", "bar"]
--   "Longest"
--   
--   
--   WARNING: This function is partial for possibly-empty structures like
--   lists.
maximumBy :: Foldable t => (a -> a -> Ordering) -> t a -> a

-- | The least element of a non-empty structure with respect to the given
--   comparison function.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> minimumBy (compare `on` length) ["Hello", "World", "!", "Longest", "bar"]
--   "!"
--   
--   
--   WARNING: This function is partial for possibly-empty structures like
--   lists.
minimumBy :: Foldable t => (a -> a -> Ordering) -> t a -> a

-- | The genericReplicate function is an overloaded version of
--   replicate, which accepts any Integral value as the
--   number of repetitions to make.
genericReplicate :: Integral i => i -> a -> [a]

-- | The genericTake function is an overloaded version of
--   take, which accepts any Integral value as the number of
--   elements to take.
genericTake :: Integral i => i -> [a] -> [a]

-- | The genericDrop function is an overloaded version of
--   drop, which accepts any Integral value as the number of
--   elements to drop.
genericDrop :: Integral i => i -> [a] -> [a]

-- | The genericSplitAt function is an overloaded version of
--   splitAt, which accepts any Integral value as the
--   position at which to split.
genericSplitAt :: Integral i => i -> [a] -> ([a], [a])

-- | The genericIndex function is an overloaded version of
--   !!, which accepts any Integral value as the index.
genericIndex :: Integral i => [a] -> i -> a

-- | Selects alphabetic Unicode characters (lower-case, upper-case and
--   title-case letters, plus letters of caseless scripts and modifiers
--   letters). This function is equivalent to isAlpha.
--   
--   This function returns True if its argument has one of the
--   following GeneralCategorys, or False otherwise:
--   
--   
--   
- UppercaseLetter
--   
- LowercaseLetter
--   
- TitlecaseLetter
--   
- ModifierLetter
--   
- OtherLetter
--   
--   
--   These classes are defined in the Unicode Character Database,
--   part of the Unicode standard. The same document defines what is and is
--   not a "Letter".
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> isLetter 'a'
--   True
--   
--   >>> isLetter 'A'
--   True
--   
--   >>> isLetter 'λ'
--   True
--   
--   >>> isLetter '0'
--   False
--   
--   >>> isLetter '%'
--   False
--   
--   >>> isLetter '♥'
--   False
--   
--   >>> isLetter '\31'
--   False
--   
--   
--   Ensure that isLetter and isAlpha are equivalent.
--   
--   
--   >>> let chars = [(chr 0)..]
--   
--   >>> let letters = map isLetter chars
--   
--   >>> let alphas = map isAlpha chars
--   
--   >>> letters == alphas
--   True
--   
isLetter :: Char -> Bool
openFile :: FilePath -> IOMode -> IO Handle

-- | Selects alphabetic Unicode characters (lower-case, upper-case and
--   title-case letters, plus letters of caseless scripts and modifiers
--   letters). This function is equivalent to isLetter.
isAlpha :: Char -> Bool

-- | The fromEnum method restricted to the type Char.
ord :: Char -> Int

-- | The toEnum method restricted to the type Char.
chr :: Int -> Char

-- | <math>. Extract the first element of a list, which must be
--   non-empty.
--   
--   
--   >>> head [1, 2, 3]
--   1
--   
--   >>> head [1..]
--   1
--   
--   >>> head []
--   *** Exception: Prelude.head: empty list
--   
--   
--   WARNING: This function is partial. You can use case-matching,
--   uncons or listToMaybe instead.
head :: HasCallStack => [a] -> a

-- | The group function takes a list and returns a list of lists
--   such that the concatenation of the result is equal to the argument.
--   Moreover, each sublist in the result is non-empty and all elements are
--   equal to the first one. For example,
--   
--   
--   >>> group "Mississippi"
--   ["M","i","ss","i","ss","i","pp","i"]
--   
--   
--   group is a special case of groupBy, which allows the
--   programmer to supply their own equality test.
--   
--   It's often preferable to use Data.List.NonEmpty.group,
--   which provides type-level guarantees of non-emptiness of inner lists.
group :: Eq a => [a] -> [[a]]

-- | The groupBy function is the non-overloaded version of
--   group.
--   
--   When a supplied relation is not transitive, it is important to
--   remember that equality is checked against the first element in the
--   group, not against the nearest neighbour:
--   
--   
--   >>> groupBy (\a b -> b - a < 5) [0..19]
--   [[0,1,2,3,4],[5,6,7,8,9],[10,11,12,13,14],[15,16,17,18,19]]
--   
--   
--   It's often preferable to use
--   Data.List.NonEmpty.groupBy, which provides type-level
--   guarantees of non-emptiness of inner lists.
groupBy :: (a -> a -> Bool) -> [a] -> [[a]]

-- | Map each element of a structure to a monadic action, evaluate these
--   actions from left to right, and collect the results. For a version
--   that ignores the results see mapM_.
--   
--   
Examples
--   
--   mapM is literally a traverse with a type signature
--   restricted to Monad. Its implementation may be more efficient
--   due to additional power of Monad.
mapM :: (Traversable t, Monad m) => (a -> m b) -> t a -> m (t b)

-- | Evaluate each monadic action in the structure from left to right, and
--   collect the results. For a version that ignores the results see
--   sequence_.
--   
--   
Examples
--   
--   Basic usage:
--   
--   The first two examples are instances where the input and and output of
--   sequence are isomorphic.
--   
--   
--   >>> sequence $ Right [1,2,3,4]
--   [Right 1,Right 2,Right 3,Right 4]
--   
--   
--   
--   >>> sequence $ [Right 1,Right 2,Right 3,Right 4]
--   Right [1,2,3,4]
--   
--   
--   The following examples demonstrate short circuit behavior for
--   sequence.
--   
--   
--   >>> sequence $ Left [1,2,3,4]
--   Left [1,2,3,4]
--   
--   
--   
--   >>> sequence $ [Left 0, Right 1,Right 2,Right 3,Right 4]
--   Left 0
--   
sequence :: (Traversable t, Monad m) => t (m a) -> m (t a)

-- | forM is mapM with its arguments flipped. For a version
--   that ignores the results see forM_.
forM :: (Traversable t, Monad m) => t a -> (a -> m b) -> m (t b)

-- | throwTo raises an arbitrary exception in the target thread (GHC
--   only).
--   
--   Exception delivery synchronizes between the source and target thread:
--   throwTo does not return until the exception has been raised in
--   the target thread. The calling thread can thus be certain that the
--   target thread has received the exception. Exception delivery is also
--   atomic with respect to other exceptions. Atomicity is a useful
--   property to have when dealing with race conditions: e.g. if there are
--   two threads that can kill each other, it is guaranteed that only one
--   of the threads will get to kill the other.
--   
--   Whatever work the target thread was doing when the exception was
--   raised is not lost: the computation is suspended until required by
--   another thread.
--   
--   If the target thread is currently making a foreign call, then the
--   exception will not be raised (and hence throwTo will not
--   return) until the call has completed. This is the case regardless of
--   whether the call is inside a mask or not. However, in GHC a
--   foreign call can be annotated as interruptible, in which case
--   a throwTo will cause the RTS to attempt to cause the call to
--   return; see the GHC documentation for more details.
--   
--   Important note: the behaviour of throwTo differs from that
--   described in the paper "Asynchronous exceptions in Haskell"
--   (http://research.microsoft.com/~simonpj/Papers/asynch-exns.htm).
--   In the paper, throwTo is non-blocking; but the library
--   implementation adopts a more synchronous design in which
--   throwTo does not return until the exception is received by the
--   target thread. The trade-off is discussed in Section 9 of the paper.
--   Like any blocking operation, throwTo is therefore interruptible
--   (see Section 5.3 of the paper). Unlike other interruptible operations,
--   however, throwTo is always interruptible, even if it
--   does not actually block.
--   
--   There is no guarantee that the exception will be delivered promptly,
--   although the runtime will endeavour to ensure that arbitrary delays
--   don't occur. In GHC, an exception can only be raised when a thread
--   reaches a safe point, where a safe point is where memory
--   allocation occurs. Some loops do not perform any memory allocation
--   inside the loop and therefore cannot be interrupted by a
--   throwTo.
--   
--   If the target of throwTo is the calling thread, then the
--   behaviour is the same as throwIO, except that the exception is
--   thrown as an asynchronous exception. This means that if there is an
--   enclosing pure computation, which would be the case if the current IO
--   operation is inside unsafePerformIO or
--   unsafeInterleaveIO, that computation is not permanently
--   replaced by the exception, but is suspended as if it had received an
--   asynchronous exception.
--   
--   Note that if throwTo is called with the current thread as the
--   target, the exception will be thrown even if the thread is currently
--   inside mask or uninterruptibleMask.
throwTo :: Exception e => ThreadId -> e -> IO ()

-- | Like forkIO, but the child thread is passed a function that can
--   be used to unmask asynchronous exceptions. This function is typically
--   used in the following way
--   
--   
--   ... mask_ $ forkIOWithUnmask $ \unmask ->
--                  catch (unmask ...) handler
--   
--   
--   so that the exception handler in the child thread is established with
--   asynchronous exceptions masked, meanwhile the main body of the child
--   thread is executed in the unmasked state.
--   
--   Note that the unmask function passed to the child thread should only
--   be used in that thread; the behaviour is undefined if it is invoked in
--   a different thread.
forkIOWithUnmask :: ((forall a. () => IO a -> IO a) -> IO ()) -> IO ThreadId

-- | Creates a new thread to run the IO computation passed as the
--   first argument, and returns the ThreadId of the newly created
--   thread.
--   
--   The new thread will be a lightweight, unbound thread. Foreign
--   calls made by this thread are not guaranteed to be made by any
--   particular OS thread; if you need foreign calls to be made by a
--   particular OS thread, then use forkOS instead.
--   
--   The new thread inherits the masked state of the parent (see
--   mask).
--   
--   The newly created thread has an exception handler that discards the
--   exceptions BlockedIndefinitelyOnMVar,
--   BlockedIndefinitelyOnSTM, and ThreadKilled, and passes
--   all other exceptions to the uncaught exception handler.
--   
--   WARNING: Exceptions in the new thread will not be rethrown in the
--   thread that created it. This means that you might be completely
--   unaware of the problem if/when this happens. You may want to use the
--   async library instead.
forkIO :: IO () -> IO ThreadId
stderr :: Handle

-- | Repeat an action indefinitely.
--   
--   
Examples
--   
--   A common use of forever is to process input from network
--   sockets, Handles, and channels (e.g. MVar and
--   Chan).
--   
--   For example, here is how we might implement an echo server,
--   using forever both to listen for client connections on a
--   network socket and to echo client input on client connection handles:
--   
--   
--   echoServer :: Socket -> IO ()
--   echoServer socket = forever $ do
--     client <- accept socket
--     forkFinally (echo client) (\_ -> hClose client)
--     where
--       echo :: Handle -> IO ()
--       echo client = forever $
--         hGetLine client >>= hPutStrLn client
--   
--   
--   Note that "forever" isn't necessarily non-terminating. If the action
--   is in a MonadPlus and short-circuits after some number
--   of iterations. then forever actually returns
--   mzero, effectively short-circuiting its caller.
forever :: Applicative f => f a -> f b

-- | The UTF-8 Unicode encoding
utf8 :: TextEncoding

-- | Look up the named Unicode encoding. May fail with
--   
--   
--   
- isDoesNotExistError if the encoding is unknown
--   
--   
--   The set of known encodings is system-dependent, but includes at least:
--   
--   
--   
- 
UTF-8

--   
- UTF-16, UTF-16BE, UTF-16LE
--   
- UTF-32, UTF-32BE, UTF-32LE
--   
--   
--   There is additional notation (borrowed from GNU iconv) for specifying
--   how illegal characters are handled:
--   
--   
--   
- a suffix of //IGNORE, e.g. UTF-8//IGNORE, will
--   cause all illegal sequences on input to be ignored, and on output will
--   drop all code points that have no representation in the target
--   encoding.
--   
- a suffix of //TRANSLIT will choose a replacement
--   character for illegal sequences or code points.
--   
- a suffix of //ROUNDTRIP will use a PEP383-style escape
--   mechanism to represent any invalid bytes in the input as Unicode
--   codepoints (specifically, as lone surrogates, which are normally
--   invalid in UTF-32). Upon output, these special codepoints are detected
--   and turned back into the corresponding original byte.
--   
--   
--   In theory, this mechanism allows arbitrary data to be roundtripped via
--   a String with no loss of data. In practice, there are two
--   limitations to be aware of:
--   
--   
--   
- This only stands a chance of working for an encoding which is an
--   ASCII superset, as for security reasons we refuse to escape any bytes
--   smaller than 128. Many encodings of interest are ASCII supersets (in
--   particular, you can assume that the locale encoding is an ASCII
--   superset) but many (such as UTF-16) are not.
--   
- If the underlying encoding is not itself roundtrippable, this
--   mechanism can fail. Roundtrippable encodings are those which have an
--   injective mapping into Unicode. Almost all encodings meet this
--   criteria, but some do not. Notably, Shift-JIS (CP932) and Big5 contain
--   several different encodings of the same Unicode codepoint.
--   
--   
--   On Windows, you can access supported code pages with the prefix
--   CP; for example, "CP1250".
mkTextEncoding :: String -> IO TextEncoding

-- | Computation hSeek hdl mode i sets the position of
--   handle hdl depending on mode. The offset i
--   is given in terms of 8-bit bytes.
--   
--   If hdl is block- or line-buffered, then seeking to a position
--   which is not in the current buffer will first cause any items in the
--   output buffer to be written to the device, and then cause the input
--   buffer to be discarded. Some handles may not be seekable (see
--   hIsSeekable), or only support a subset of the possible
--   positioning operations (for instance, it may only be possible to seek
--   to the end of a tape, or to a positive offset from the beginning or
--   current position). It is not possible to set a negative I/O position,
--   or for a physical file, an I/O position beyond the current
--   end-of-file.
--   
--   This operation may fail with:
--   
--   
--   
- isIllegalOperationError if the Handle is not seekable, or
--   does not support the requested seek mode.
--   
- isPermissionError if a system resource limit would be
--   exceeded.
--   
hSeek :: Handle -> SeekMode -> Integer -> IO ()

-- | Similar to listDirectory, but always includes the special
--   entries (. and ..). (This applies to Windows as
--   well.)
--   
--   The operation may fail with the same exceptions as
--   listDirectory.
getDirectoryContents :: FilePath -> IO [FilePath]

-- | The action hFlush hdl causes any items buffered for
--   output in handle hdl to be sent immediately to the operating
--   system.
--   
--   This operation may fail with:
--   
--   
--   
- isFullError if the device is full;
--   
- isPermissionError if a system resource limit would be
--   exceeded. It is unspecified whether the characters in the buffer are
--   discarded or retained under these circumstances.
--   
hFlush :: Handle -> IO ()

-- | Computation hLookAhead returns the next character from the
--   handle without removing it from the input buffer, blocking until a
--   character is available.
--   
--   This operation may fail with:
--   
--   
--   
- isEOFError if the end of file has been reached.
--   
hLookAhead :: Handle -> IO Char

-- | The implementation of mfix for IO. If the function
--   passed to fixIO inspects its argument, the resulting action
--   will throw FixIOException.
fixIO :: (a -> IO a) -> IO a

-- | killThread raises the ThreadKilled exception in the
--   given thread (GHC only).
--   
--   
--   killThread tid = throwTo tid ThreadKilled
--   
killThread :: ThreadId -> IO ()

-- | Suspends the current thread for a given number of microseconds (GHC
--   only).
--   
--   There is no guarantee that the thread will be rescheduled promptly
--   when the delay has expired, but the thread will never continue to run
--   earlier than specified.
--   
--   Be careful not to exceed maxBound :: Int, which on 32-bit
--   machines is only 2147483647 μs, less than 36 minutes. Consider using
--   Control.Concurrent.Thread.Delay.delay from
--   unbounded-delays package.
threadDelay :: Int -> IO ()

-- | Like forkIO, this sparks off a new thread to run the IO
--   computation passed as the first argument, and returns the
--   ThreadId of the newly created thread.
--   
--   However, forkOS creates a bound thread, which is
--   necessary if you need to call foreign (non-Haskell) libraries that
--   make use of thread-local state, such as OpenGL (see
--   Control.Concurrent#boundthreads).
--   
--   Using forkOS instead of forkIO makes no difference at
--   all to the scheduling behaviour of the Haskell runtime system. It is a
--   common misconception that you need to use forkOS instead of
--   forkIO to avoid blocking all the Haskell threads when making a
--   foreign call; this isn't the case. To allow foreign calls to be made
--   without blocking all the Haskell threads (with GHC), it is only
--   necessary to use the -threaded option when linking your
--   program, and to make sure the foreign import is not marked
--   unsafe.
forkOS :: IO () -> IO ThreadId

-- | The readFile' function reads a file and returns the contents of
--   the file as a string. The file is fully read before being returned, as
--   with getContents'.
readFile' :: FilePath -> IO String

-- | The computation writeFile file str function writes the
--   string str, to the file file.
writeFile :: FilePath -> String -> IO ()

-- | Read a line from the standard input device (same as hGetLine
--   stdin).
getLine :: IO String

-- | The same as putStr, but adds a newline character.
putStrLn :: String -> IO ()

-- | An error indicating that an IO operation failed because one of
--   its arguments does not exist.
isDoesNotExistError :: IOError -> Bool

-- | Computation getArgs returns a list of the program's command
--   line arguments (not including the program name).
getArgs :: IO [String]

-- | Set the NewlineMode on the specified Handle. All
--   buffered data is flushed first.
hSetNewlineMode :: Handle -> NewlineMode -> IO ()

-- | Computation hClose hdl makes handle hdl
--   closed. Before the computation finishes, if hdl is writable
--   its buffer is flushed as for hFlush. Performing hClose
--   on a handle that has already been closed has no effect; doing so is
--   not an error. All other operations on a closed handle will fail. If
--   hClose fails for any reason, any further operations (apart from
--   hClose) on the handle will still fail as if hdl had
--   been successfully closed.
--   
--   hClose is an interruptible operation in the sense
--   described in Control.Exception. If hClose is interrupted
--   by an asynchronous exception in the process of flushing its buffers,
--   then the I/O device (e.g., file) will be closed anyway.
hClose :: Handle -> IO ()

-- | An error indicating that an IO operation failed because one of
--   its arguments is a single-use resource, which is already being used
--   (for example, opening the same file twice for writing might give this
--   error).
isAlreadyInUseError :: IOError -> Bool

-- | An error indicating that an IO operation failed because the
--   user does not have sufficient operating system privilege to perform
--   that operation.
isPermissionError :: IOError -> Bool

-- | Select binary mode (True) or text mode (False) on a open
--   handle. (See also openBinaryFile.)
--   
--   This has the same effect as calling hSetEncoding with
--   char8, together with hSetNewlineMode with
--   noNewlineTranslation.
hSetBinaryMode :: Handle -> Bool -> IO ()

-- | An error indicating that an IO operation failed because the
--   device is full.
isFullError :: IOError -> Bool

-- | An error indicating that an IO operation failed because the end
--   of file has been reached.
isEOFError :: IOError -> Bool

-- | The Unicode encoding of the current locale
--   
--   This is the initial locale encoding: if it has been subsequently
--   changed by setLocaleEncoding this value will not reflect that
--   change.
localeEncoding :: TextEncoding

-- | An error indicating that an IO operation failed because the
--   operation was not possible. Any computation which returns an IO
--   result may fail with isIllegalOperation. In some cases, an
--   implementation will not be able to distinguish between the possible
--   error causes. In this case it should fail with
--   isIllegalOperation.
isIllegalOperation :: IOError -> Bool

-- | Promote a function to a monad.
liftM :: Monad m => (a1 -> r) -> m a1 -> m r

-- | Fork a thread and call the supplied function when the thread is about
--   to terminate, with an exception or a returned value. The function is
--   called with asynchronous exceptions masked.
--   
--   
--   forkFinally action and_then =
--     mask $ \restore ->
--       forkIO $ try (restore action) >>= and_then
--   
--   
--   This function is useful for informing the parent when a child
--   terminates, for example.
forkFinally :: IO a -> (Either SomeException a -> IO ()) -> IO ThreadId

-- | Computation getEnv var returns the value of the
--   environment variable var. For the inverse, the setEnv
--   function can be used.
--   
--   This computation may fail with:
--   
--   
--   
- isDoesNotExistError if the environment variable does not
--   exist.
--   
getEnv :: String -> IO String

-- | setEnv name value sets the specified environment variable to
--   value.
--   
--   Early versions of this function operated under the mistaken belief
--   that setting an environment variable to the empty string on
--   Windows removes that environment variable from the environment. For
--   the sake of compatibility, it adopted that behavior on POSIX. In
--   particular
--   
--   
--   setEnv name ""
--   
--   
--   has the same effect as
--   
--   
--   unsetEnv name
--   
--   
--   If you'd like to be able to set environment variables to blank
--   strings, use setEnv.
--   
--   Throws IOException if name is the empty string or
--   contains an equals sign.
setEnv :: String -> String -> IO ()

-- | Return the value of the environment variable var, or
--   Nothing if there is no such value.
--   
--   For POSIX users, this is equivalent to getEnv.
lookupEnv :: String -> IO (Maybe String)

-- | unsetEnv name removes the specified environment variable from
--   the environment of the current process.
--   
--   Throws IOException if name is the empty string or
--   contains an equals sign.
unsetEnv :: String -> IO ()

-- | The unfoldr function is a `dual' to foldr: while
--   foldr reduces a list to a summary value, unfoldr builds
--   a list from a seed value. The function takes the element and returns
--   Nothing if it is done producing the list or returns Just
--   (a,b), in which case, a is a prepended to the list
--   and b is used as the next element in a recursive call. For
--   example,
--   
--   
--   iterate f == unfoldr (\x -> Just (x, f x))
--   
--   
--   In some cases, unfoldr can undo a foldr operation:
--   
--   
--   unfoldr f' (foldr f z xs) == xs
--   
--   
--   if the following holds:
--   
--   
--   f' (f x y) = Just (x,y)
--   f' z       = Nothing
--   
--   
--   A simple use of unfoldr:
--   
--   
--   >>> unfoldr (\b -> if b == 0 then Nothing else Just (b, b-1)) 10
--   [10,9,8,7,6,5,4,3,2,1]
--   
unfoldr :: (b -> Maybe (a, b)) -> b -> [a]

-- | The transpose function transposes the rows and columns of its
--   argument. For example,
--   
--   
--   >>> transpose [[1,2,3],[4,5,6]]
--   [[1,4],[2,5],[3,6]]
--   
--   
--   If some of the rows are shorter than the following rows, their
--   elements are skipped:
--   
--   
--   >>> transpose [[10,11],[20],[],[30,31,32]]
--   [[10,20,30],[11,31],[32]]
--   
--   
--   For this reason the outer list must be finite; otherwise
--   transpose hangs:
--   
--   
--   >>> transpose (repeat [])
--   * Hangs forever *
--   
transpose :: [[a]] -> [[a]]

-- | Computation exitWith code throws ExitCode
--   code. Normally this terminates the program, returning
--   code to the program's caller.
--   
--   On program termination, the standard Handles stdout and
--   stderr are flushed automatically; any other buffered
--   Handles need to be flushed manually, otherwise the buffered
--   data will be discarded.
--   
--   A program that fails in any other way is treated as if it had called
--   exitFailure. A program that terminates successfully without
--   calling exitWith explicitly is treated as if it had called
--   exitWith ExitSuccess.
--   
--   As an ExitCode is an Exception, it can be caught using
--   the functions of Control.Exception. This means that cleanup
--   computations added with bracket (from Control.Exception)
--   are also executed properly on exitWith.
--   
--   Note: in GHC, exitWith should be called from the main program
--   thread in order to exit the process. When called from another thread,
--   exitWith will throw an ExitCode as normal, but the
--   exception will not cause the process itself to exit.
exitWith :: ExitCode -> IO a

-- | hGetBuf hdl buf count reads data from the handle
--   hdl into the buffer buf until either EOF is reached
--   or count 8-bit bytes have been read. It returns the number of
--   bytes actually read. This may be zero if EOF was reached before any
--   data was read (or if count is zero).
--   
--   hGetBuf never raises an EOF exception, instead it returns a
--   value smaller than count.
--   
--   If the handle is a pipe or socket, and the writing end is closed,
--   hGetBuf will behave as if EOF was reached.
--   
--   hGetBuf ignores the prevailing TextEncoding and
--   NewlineMode on the Handle, and reads bytes directly.
hGetBuf :: Handle -> Ptr a -> Int -> IO Int

-- | hPutBuf hdl buf count writes count 8-bit
--   bytes from the buffer buf to the handle hdl. It
--   returns ().
--   
--   hPutBuf ignores any text encoding that applies to the
--   Handle, writing the bytes directly to the underlying file or
--   device.
--   
--   hPutBuf ignores the prevailing TextEncoding and
--   NewlineMode on the Handle, and writes bytes directly.
--   
--   This operation may fail with:
--   
--   
--   
- ResourceVanished if the handle is a pipe or socket, and the
--   reading end is closed. (If this is a POSIX system, and the program has
--   not asked to ignore SIGPIPE, then a SIGPIPE may be delivered instead,
--   whose default action is to terminate the program).
--   
hPutBuf :: Handle -> Ptr a -> Int -> IO ()

-- | Computation hWaitForInput hdl t waits until input is
--   available on handle hdl. It returns True as soon as
--   input is available on hdl, or False if no input is
--   available within t milliseconds. Note that
--   hWaitForInput waits until one or more full characters
--   are available, which means that it needs to do decoding, and hence may
--   fail with a decoding error.
--   
--   If t is less than zero, then hWaitForInput waits
--   indefinitely.
--   
--   This operation may fail with:
--   
--   
--   
- isEOFError if the end of file has been reached.
--   
- a decoding error, if the input begins with an invalid byte
--   sequence in this Handle's encoding.
--   
--   
--   NOTE for GHC users: unless you use the -threaded flag,
--   hWaitForInput hdl t where t >= 0 will block all
--   other Haskell threads for the duration of the call. It behaves like a
--   safe foreign call in this respect.
hWaitForInput :: Handle -> Int -> IO Bool

-- | Sort a list by comparing the results of a key function applied to each
--   element. sortOn f is equivalent to sortBy
--   (comparing f), but has the performance advantage of only
--   evaluating f once for each element in the input list. This is
--   called the decorate-sort-undecorate paradigm, or Schwartzian
--   transform.
--   
--   Elements are arranged from lowest to highest, keeping duplicates in
--   the order they appeared in the input.
--   
--   
--   >>> sortOn fst [(2, "world"), (4, "!"), (1, "Hello")]
--   [(1,"Hello"),(2,"world"),(4,"!")]
--   
--   
--   The argument must be finite.
sortOn :: Ord b => (a -> b) -> [a] -> [a]

-- | cycle ties a finite list into a circular one, or equivalently,
--   the infinite repetition of the original list. It is the identity on
--   infinite lists.
--   
--   
--   >>> cycle []
--   *** Exception: Prelude.cycle: empty list
--   
--   >>> cycle [42]
--   [42,42,42,42,42,42,42,42,42,42...
--   
--   >>> cycle [2, 5, 7]
--   [2,5,7,2,5,7,2,5,7,2,5,7...
--   
cycle :: HasCallStack => [a] -> [a]

-- | The concatenation of all the elements of a container of lists.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> concat (Just [1, 2, 3])
--   [1,2,3]
--   
--   
--   
--   >>> concat (Left 42)
--   []
--   
--   
--   
--   >>> concat [[1, 2, 3], [4, 5], [6], []]
--   [1,2,3,4,5,6]
--   
concat :: Foldable t => t [a] -> [a]

-- | <math>. zip takes two lists and returns a list of
--   corresponding pairs.
--   
--   
--   >>> zip [1, 2] ['a', 'b']
--   [(1,'a'),(2,'b')]
--   
--   
--   If one input list is shorter than the other, excess elements of the
--   longer list are discarded, even if one of the lists is infinite:
--   
--   
--   >>> zip [1] ['a', 'b']
--   [(1,'a')]
--   
--   >>> zip [1, 2] ['a']
--   [(1,'a')]
--   
--   >>> zip [] [1..]
--   []
--   
--   >>> zip [1..] []
--   []
--   
--   
--   zip is right-lazy:
--   
--   
--   >>> zip [] undefined
--   []
--   
--   >>> zip undefined []
--   *** Exception: Prelude.undefined
--   ...
--   
--   
--   zip is capable of list fusion, but it is restricted to its
--   first list argument and its resulting list.
zip :: [a] -> [b] -> [(a, b)]

-- | The print function outputs a value of any printable type to the
--   standard output device. Printable types are those that are instances
--   of class Show; print converts values to strings for
--   output using the show operation and adds a newline.
--   
--   For example, a program to print the first 20 integers and their powers
--   of 2 could be written as:
--   
--   
--   main = print ([(n, 2^n) | n <- [0..19]])
--   
print :: Show a => a -> IO ()

-- | The trace function outputs the trace message given as its first
--   argument, before returning the second argument as its result.
--   
--   For example, this returns the value of f x and outputs the
--   message to stderr. Depending on your terminal (settings), they may or
--   may not be mixed.
--   
--   
--   >>> let x = 123; f = show
--   
--   >>> trace ("calling f with x = " ++ show x) (f x)
--   calling f with x = 123
--   "123"
--   
--   
--   The trace function should only be used for debugging, or
--   for monitoring execution. The function is not referentially
--   transparent: its type indicates that it is a pure function but it has
--   the side effect of outputting the trace message.
trace :: String -> a -> a

-- | Conditional failure of Alternative computations. Defined by
--   
--   
--   guard True  = pure ()
--   guard False = empty
--   
--   
--   
Examples
--   
--   Common uses of guard include conditionally signaling an error
--   in an error monad and conditionally rejecting the current choice in an
--   Alternative-based parser.
--   
--   As an example of signaling an error in the error monad Maybe,
--   consider a safe division function safeDiv x y that returns
--   Nothing when the denominator y is zero and
--   Just (x `div` y) otherwise. For example:
--   
--   
--   >>> safeDiv 4 0
--   Nothing
--   
--   
--   
--   >>> safeDiv 4 2
--   Just 2
--   
--   
--   A definition of safeDiv using guards, but not guard:
--   
--   
--   safeDiv :: Int -> Int -> Maybe Int
--   safeDiv x y | y /= 0    = Just (x `div` y)
--               | otherwise = Nothing
--   
--   
--   A definition of safeDiv using guard and Monad
--   do-notation:
--   
--   
--   safeDiv :: Int -> Int -> Maybe Int
--   safeDiv x y = do
--     guard (y /= 0)
--     return (x `div` y)
--   
guard :: Alternative f => Bool -> f ()

-- | A variant of <*> with the arguments reversed.
(<**>) :: Applicative f => f a -> f (a -> b) -> f b
infixl 4 <**>

-- | Lift a function to actions. Equivalent to Functor's fmap but
--   implemented using only Applicative's methods: liftA
--   f a = pure f <*> a
--   
--   As such this function may be used to implement a Functor
--   instance from an Applicative one.
--   
--   
Examples
--   
--   Using the Applicative instance for Lists:
--   
--   
--   >>> liftA (+1) [1, 2]
--   [2,3]
--   
--   
--   Or the Applicative instance for Maybe
--   
--   
--   >>> liftA (+1) (Just 3)
--   Just 4
--   
liftA :: Applicative f => (a -> b) -> f a -> f b

-- | Lift a ternary function to actions.
liftA3 :: Applicative f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d

-- | Same as >>=, but with the arguments interchanged.
(=<<) :: Monad m => (a -> m b) -> m a -> m b
infixr 1 =<<

-- | Conditional execution of Applicative expressions. For example,
--   
--   
--   when debug (putStrLn "Debugging")
--   
--   
--   will output the string Debugging if the Boolean value
--   debug is True, and otherwise do nothing.
when :: Applicative f => Bool -> f () -> f ()

-- | Promote a function to a monad, scanning the monadic arguments from
--   left to right. For example,
--   
--   
--   liftM2 (+) [0,1] [0,2] = [0,2,1,3]
--   liftM2 (+) (Just 1) Nothing = Nothing
--   
liftM2 :: Monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r

-- | Promote a function to a monad, scanning the monadic arguments from
--   left to right (cf. liftM2).
liftM3 :: Monad m => (a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r

-- | Promote a function to a monad, scanning the monadic arguments from
--   left to right (cf. liftM2).
liftM4 :: Monad m => (a1 -> a2 -> a3 -> a4 -> r) -> m a1 -> m a2 -> m a3 -> m a4 -> m r

-- | Promote a function to a monad, scanning the monadic arguments from
--   left to right (cf. liftM2).
liftM5 :: Monad m => (a1 -> a2 -> a3 -> a4 -> a5 -> r) -> m a1 -> m a2 -> m a3 -> m a4 -> m a5 -> m r

-- | In many situations, the liftM operations can be replaced by
--   uses of ap, which promotes function application.
--   
--   
--   return f `ap` x1 `ap` ... `ap` xn
--   
--   
--   is equivalent to
--   
--   
--   liftMn f x1 x2 ... xn
--   
ap :: Monad m => m (a -> b) -> m a -> m b

-- | The maybe function takes a default value, a function, and a
--   Maybe value. If the Maybe value is Nothing, the
--   function returns the default value. Otherwise, it applies the function
--   to the value inside the Just and returns the result.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> maybe False odd (Just 3)
--   True
--   
--   
--   
--   >>> maybe False odd Nothing
--   False
--   
--   
--   Read an integer from a string using readMaybe. If we succeed,
--   return twice the integer; that is, apply (*2) to it. If
--   instead we fail to parse an integer, return 0 by default:
--   
--   
--   >>> import Text.Read ( readMaybe )
--   
--   >>> maybe 0 (*2) (readMaybe "5")
--   10
--   
--   >>> maybe 0 (*2) (readMaybe "")
--   0
--   
--   
--   Apply show to a Maybe Int. If we have Just n,
--   we want to show the underlying Int n. But if we have
--   Nothing, we return the empty string instead of (for example)
--   "Nothing":
--   
--   
--   >>> maybe "" show (Just 5)
--   "5"
--   
--   >>> maybe "" show Nothing
--   ""
--   
maybe :: b -> (a -> b) -> Maybe a -> b

-- | The isJust function returns True iff its argument is of
--   the form Just _.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> isJust (Just 3)
--   True
--   
--   
--   
--   >>> isJust (Just ())
--   True
--   
--   
--   
--   >>> isJust Nothing
--   False
--   
--   
--   Only the outer constructor is taken into consideration:
--   
--   
--   >>> isJust (Just Nothing)
--   True
--   
isJust :: Maybe a -> Bool

-- | The isNothing function returns True iff its argument is
--   Nothing.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> isNothing (Just 3)
--   False
--   
--   
--   
--   >>> isNothing (Just ())
--   False
--   
--   
--   
--   >>> isNothing Nothing
--   True
--   
--   
--   Only the outer constructor is taken into consideration:
--   
--   
--   >>> isNothing (Just Nothing)
--   False
--   
isNothing :: Maybe a -> Bool

-- | The fromJust function extracts the element out of a Just
--   and throws an error if its argument is Nothing.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> fromJust (Just 1)
--   1
--   
--   
--   
--   >>> 2 * (fromJust (Just 10))
--   20
--   
--   
--   
--   >>> 2 * (fromJust Nothing)
--   *** Exception: Maybe.fromJust: Nothing
--   ...
--   
--   
--   WARNING: This function is partial. You can use case-matching instead.
fromJust :: HasCallStack => Maybe a -> a

-- | The fromMaybe function takes a default value and a Maybe
--   value. If the Maybe is Nothing, it returns the default
--   value; otherwise, it returns the value contained in the Maybe.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> fromMaybe "" (Just "Hello, World!")
--   "Hello, World!"
--   
--   
--   
--   >>> fromMaybe "" Nothing
--   ""
--   
--   
--   Read an integer from a string using readMaybe. If we fail to
--   parse an integer, we want to return 0 by default:
--   
--   
--   >>> import Text.Read ( readMaybe )
--   
--   >>> fromMaybe 0 (readMaybe "5")
--   5
--   
--   >>> fromMaybe 0 (readMaybe "")
--   0
--   
fromMaybe :: a -> Maybe a -> a

-- | The maybeToList function returns an empty list when given
--   Nothing or a singleton list when given Just.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> maybeToList (Just 7)
--   [7]
--   
--   
--   
--   >>> maybeToList Nothing
--   []
--   
--   
--   One can use maybeToList to avoid pattern matching when combined
--   with a function that (safely) works on lists:
--   
--   
--   >>> import Text.Read ( readMaybe )
--   
--   >>> sum $ maybeToList (readMaybe "3")
--   3
--   
--   >>> sum $ maybeToList (readMaybe "")
--   0
--   
maybeToList :: Maybe a -> [a]

-- | The listToMaybe function returns Nothing on an empty
--   list or Just a where a is the first element
--   of the list.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> listToMaybe []
--   Nothing
--   
--   
--   
--   >>> listToMaybe [9]
--   Just 9
--   
--   
--   
--   >>> listToMaybe [1,2,3]
--   Just 1
--   
--   
--   Composing maybeToList with listToMaybe should be the
--   identity on singleton/empty lists:
--   
--   
--   >>> maybeToList $ listToMaybe [5]
--   [5]
--   
--   >>> maybeToList $ listToMaybe []
--   []
--   
--   
--   But not on lists with more than one element:
--   
--   
--   >>> maybeToList $ listToMaybe [1,2,3]
--   [1]
--   
listToMaybe :: [a] -> Maybe a

-- | The catMaybes function takes a list of Maybes and
--   returns a list of all the Just values.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> catMaybes [Just 1, Nothing, Just 3]
--   [1,3]
--   
--   
--   When constructing a list of Maybe values, catMaybes can
--   be used to return all of the "success" results (if the list is the
--   result of a map, then mapMaybe would be more
--   appropriate):
--   
--   
--   >>> import Text.Read ( readMaybe )
--   
--   >>> [readMaybe x :: Maybe Int | x <- ["1", "Foo", "3"] ]
--   [Just 1,Nothing,Just 3]
--   
--   >>> catMaybes $ [readMaybe x :: Maybe Int | x <- ["1", "Foo", "3"] ]
--   [1,3]
--   
catMaybes :: [Maybe a] -> [a]

-- | <math>. Decompose a list into its head and tail.
--   
--   
--   
- If the list is empty, returns Nothing.
--   
- If the list is non-empty, returns Just (x, xs),
--   where x is the head of the list and xs its
--   tail.
--   
--   
--   
--   >>> uncons []
--   Nothing
--   
--   >>> uncons [1]
--   Just (1,[])
--   
--   >>> uncons [1, 2, 3]
--   Just (1,[2,3])
--   
uncons :: [a] -> Maybe (a, [a])

-- | <math>. Extract the elements after the head of a list, which
--   must be non-empty.
--   
--   
--   >>> tail [1, 2, 3]
--   [2,3]
--   
--   >>> tail [1]
--   []
--   
--   >>> tail []
--   *** Exception: Prelude.tail: empty list
--   
--   
--   WARNING: This function is partial. You can use case-matching or
--   uncons instead.
tail :: HasCallStack => [a] -> [a]

-- | <math>. Extract the last element of a list, which must be finite
--   and non-empty.
--   
--   
--   >>> last [1, 2, 3]
--   3
--   
--   >>> last [1..]
--   * Hangs forever *
--   
--   >>> last []
--   *** Exception: Prelude.last: empty list
--   
--   
--   WARNING: This function is partial. You can use reverse with
--   case-matching, uncons or listToMaybe instead.
last :: HasCallStack => [a] -> a

-- | <math>. Return all the elements of a list except the last one.
--   The list must be non-empty.
--   
--   
--   >>> init [1, 2, 3]
--   [1,2]
--   
--   >>> init [1]
--   []
--   
--   >>> init []
--   *** Exception: Prelude.init: empty list
--   
--   
--   WARNING: This function is partial. You can use reverse with
--   case-matching or uncons instead.
init :: HasCallStack => [a] -> [a]

-- | A strict version of foldl1.
foldl1' :: HasCallStack => (a -> a -> a) -> [a] -> a

-- | <math>. scanl is similar to foldl, but returns a
--   list of successive reduced values from the left:
--   
--   
--   scanl f z [x1, x2, ...] == [z, z `f` x1, (z `f` x1) `f` x2, ...]
--   
--   
--   Note that
--   
--   
--   last (scanl f z xs) == foldl f z xs
--   
--   
--   
--   >>> scanl (+) 0 [1..4]
--   [0,1,3,6,10]
--   
--   >>> scanl (+) 42 []
--   [42]
--   
--   >>> scanl (-) 100 [1..4]
--   [100,99,97,94,90]
--   
--   >>> scanl (\reversedString nextChar -> nextChar : reversedString) "foo" ['a', 'b', 'c', 'd']
--   ["foo","afoo","bafoo","cbafoo","dcbafoo"]
--   
--   >>> scanl (+) 0 [1..]
--   * Hangs forever *
--   
scanl :: (b -> a -> b) -> b -> [a] -> [b]

-- | <math>. scanl1 is a variant of scanl that has no
--   starting value argument:
--   
--   
--   scanl1 f [x1, x2, ...] == [x1, x1 `f` x2, ...]
--   
--   
--   
--   >>> scanl1 (+) [1..4]
--   [1,3,6,10]
--   
--   >>> scanl1 (+) []
--   []
--   
--   >>> scanl1 (-) [1..4]
--   [1,-1,-4,-8]
--   
--   >>> scanl1 (&&) [True, False, True, True]
--   [True,False,False,False]
--   
--   >>> scanl1 (||) [False, False, True, True]
--   [False,False,True,True]
--   
--   >>> scanl1 (+) [1..]
--   * Hangs forever *
--   
scanl1 :: (a -> a -> a) -> [a] -> [a]

-- | <math>. A strict version of scanl.
scanl' :: (b -> a -> b) -> b -> [a] -> [b]

-- | <math>. scanr is the right-to-left dual of scanl.
--   Note that the order of parameters on the accumulating function are
--   reversed compared to scanl. Also note that
--   
--   
--   head (scanr f z xs) == foldr f z xs.
--   
--   
--   
--   >>> scanr (+) 0 [1..4]
--   [10,9,7,4,0]
--   
--   >>> scanr (+) 42 []
--   [42]
--   
--   >>> scanr (-) 100 [1..4]
--   [98,-97,99,-96,100]
--   
--   >>> scanr (\nextChar reversedString -> nextChar : reversedString) "foo" ['a', 'b', 'c', 'd']
--   ["abcdfoo","bcdfoo","cdfoo","dfoo","foo"]
--   
--   >>> force $ scanr (+) 0 [1..]
--   *** Exception: stack overflow
--   
scanr :: (a -> b -> b) -> b -> [a] -> [b]

-- | <math>. scanr1 is a variant of scanr that has no
--   starting value argument.
--   
--   
--   >>> scanr1 (+) [1..4]
--   [10,9,7,4]
--   
--   >>> scanr1 (+) []
--   []
--   
--   >>> scanr1 (-) [1..4]
--   [-2,3,-1,4]
--   
--   >>> scanr1 (&&) [True, False, True, True]
--   [False,False,True,True]
--   
--   >>> scanr1 (||) [True, True, False, False]
--   [True,True,False,False]
--   
--   >>> force $ scanr1 (+) [1..]
--   *** Exception: stack overflow
--   
scanr1 :: (a -> a -> a) -> [a] -> [a]

-- | iterate f x returns an infinite list of repeated
--   applications of f to x:
--   
--   
--   iterate f x == [x, f x, f (f x), ...]
--   
--   
--   Note that iterate is lazy, potentially leading to thunk
--   build-up if the consumer doesn't force each iterate. See
--   iterate' for a strict variant of this function.
--   
--   
--   >>> take 10 $ iterate not True
--   [True,False,True,False...
--   
--   >>> take 10 $ iterate (+3) 42
--   [42,45,48,51,54,57,60,63...
--   
iterate :: (a -> a) -> a -> [a]

-- | iterate' is the strict version of iterate.
--   
--   It forces the result of each application of the function to weak head
--   normal form (WHNF) before proceeding.
iterate' :: (a -> a) -> a -> [a]

-- | repeat x is an infinite list, with x the
--   value of every element.
--   
--   
--   >>> repeat 17
--   [17,17,17,17,17,17,17,17,17...
--   
repeat :: a -> [a]

-- | replicate n x is a list of length n with
--   x the value of every element. It is an instance of the more
--   general genericReplicate, in which n may be of any
--   integral type.
--   
--   
--   >>> replicate 0 True
--   []
--   
--   >>> replicate (-1) True
--   []
--   
--   >>> replicate 4 True
--   [True,True,True,True]
--   
replicate :: Int -> a -> [a]

-- | takeWhile, applied to a predicate p and a list
--   xs, returns the longest prefix (possibly empty) of
--   xs of elements that satisfy p.
--   
--   
--   >>> takeWhile (< 3) [1,2,3,4,1,2,3,4]
--   [1,2]
--   
--   >>> takeWhile (< 9) [1,2,3]
--   [1,2,3]
--   
--   >>> takeWhile (< 0) [1,2,3]
--   []
--   
takeWhile :: (a -> Bool) -> [a] -> [a]

-- | dropWhile p xs returns the suffix remaining after
--   takeWhile p xs.
--   
--   
--   >>> dropWhile (< 3) [1,2,3,4,5,1,2,3]
--   [3,4,5,1,2,3]
--   
--   >>> dropWhile (< 9) [1,2,3]
--   []
--   
--   >>> dropWhile (< 0) [1,2,3]
--   [1,2,3]
--   
dropWhile :: (a -> Bool) -> [a] -> [a]

-- | take n, applied to a list xs, returns the
--   prefix of xs of length n, or xs itself if
--   n >= length xs.
--   
--   
--   >>> take 5 "Hello World!"
--   "Hello"
--   
--   >>> take 3 [1,2,3,4,5]
--   [1,2,3]
--   
--   >>> take 3 [1,2]
--   [1,2]
--   
--   >>> take 3 []
--   []
--   
--   >>> take (-1) [1,2]
--   []
--   
--   >>> take 0 [1,2]
--   []
--   
--   
--   It is an instance of the more general genericTake, in which
--   n may be of any integral type.
take :: Int -> [a] -> [a]

-- | drop n xs returns the suffix of xs after the
--   first n elements, or [] if n >= length
--   xs.
--   
--   
--   >>> drop 6 "Hello World!"
--   "World!"
--   
--   >>> drop 3 [1,2,3,4,5]
--   [4,5]
--   
--   >>> drop 3 [1,2]
--   []
--   
--   >>> drop 3 []
--   []
--   
--   >>> drop (-1) [1,2]
--   [1,2]
--   
--   >>> drop 0 [1,2]
--   [1,2]
--   
--   
--   It is an instance of the more general genericDrop, in which
--   n may be of any integral type.
drop :: Int -> [a] -> [a]

-- | splitAt n xs returns a tuple where first element is
--   xs prefix of length n and second element is the
--   remainder of the list:
--   
--   
--   >>> splitAt 6 "Hello World!"
--   ("Hello ","World!")
--   
--   >>> splitAt 3 [1,2,3,4,5]
--   ([1,2,3],[4,5])
--   
--   >>> splitAt 1 [1,2,3]
--   ([1],[2,3])
--   
--   >>> splitAt 3 [1,2,3]
--   ([1,2,3],[])
--   
--   >>> splitAt 4 [1,2,3]
--   ([1,2,3],[])
--   
--   >>> splitAt 0 [1,2,3]
--   ([],[1,2,3])
--   
--   >>> splitAt (-1) [1,2,3]
--   ([],[1,2,3])
--   
--   
--   It is equivalent to (take n xs, drop n xs) when
--   n is not _|_ (splitAt _|_ xs = _|_).
--   splitAt is an instance of the more general
--   genericSplitAt, in which n may be of any integral
--   type.
splitAt :: Int -> [a] -> ([a], [a])

-- | span, applied to a predicate p and a list xs,
--   returns a tuple where first element is longest prefix (possibly empty)
--   of xs of elements that satisfy p and second element
--   is the remainder of the list:
--   
--   
--   >>> span (< 3) [1,2,3,4,1,2,3,4]
--   ([1,2],[3,4,1,2,3,4])
--   
--   >>> span (< 9) [1,2,3]
--   ([1,2,3],[])
--   
--   >>> span (< 0) [1,2,3]
--   ([],[1,2,3])
--   
--   
--   span p xs is equivalent to (takeWhile p xs,
--   dropWhile p xs)
span :: (a -> Bool) -> [a] -> ([a], [a])

-- | break, applied to a predicate p and a list
--   xs, returns a tuple where first element is longest prefix
--   (possibly empty) of xs of elements that do not satisfy
--   p and second element is the remainder of the list:
--   
--   
--   >>> break (> 3) [1,2,3,4,1,2,3,4]
--   ([1,2,3],[4,1,2,3,4])
--   
--   >>> break (< 9) [1,2,3]
--   ([],[1,2,3])
--   
--   >>> break (> 9) [1,2,3]
--   ([1,2,3],[])
--   
--   
--   break p is equivalent to span (not .
--   p).
break :: (a -> Bool) -> [a] -> ([a], [a])

-- | reverse xs returns the elements of xs in
--   reverse order. xs must be finite.
--   
--   
--   >>> reverse []
--   []
--   
--   >>> reverse [42]
--   [42]
--   
--   >>> reverse [2,5,7]
--   [7,5,2]
--   
--   >>> reverse [1..]
--   * Hangs forever *
--   
reverse :: [a] -> [a]

-- | and returns the conjunction of a container of Bools. For the
--   result to be True, the container must be finite; False,
--   however, results from a False value finitely far from the left
--   end.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> and []
--   True
--   
--   
--   
--   >>> and [True]
--   True
--   
--   
--   
--   >>> and [False]
--   False
--   
--   
--   
--   >>> and [True, True, False]
--   False
--   
--   
--   
--   >>> and (False : repeat True) -- Infinite list [False,True,True,True,...
--   False
--   
--   
--   
--   >>> and (repeat True)
--   * Hangs forever *
--   
and :: Foldable t => t Bool -> Bool

-- | or returns the disjunction of a container of Bools. For the
--   result to be False, the container must be finite; True,
--   however, results from a True value finitely far from the left
--   end.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> or []
--   False
--   
--   
--   
--   >>> or [True]
--   True
--   
--   
--   
--   >>> or [False]
--   False
--   
--   
--   
--   >>> or [True, True, False]
--   True
--   
--   
--   
--   >>> or (True : repeat False) -- Infinite list [True,False,False,False,...
--   True
--   
--   
--   
--   >>> or (repeat False)
--   * Hangs forever *
--   
or :: Foldable t => t Bool -> Bool

-- | Determines whether any element of the structure satisfies the
--   predicate.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> any (> 3) []
--   False
--   
--   
--   
--   >>> any (> 3) [1,2]
--   False
--   
--   
--   
--   >>> any (> 3) [1,2,3,4,5]
--   True
--   
--   
--   
--   >>> any (> 3) [1..]
--   True
--   
--   
--   
--   >>> any (> 3) [0, -1..]
--   * Hangs forever *
--   
any :: Foldable t => (a -> Bool) -> t a -> Bool

-- | Determines whether all elements of the structure satisfy the
--   predicate.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> all (> 3) []
--   True
--   
--   
--   
--   >>> all (> 3) [1,2]
--   False
--   
--   
--   
--   >>> all (> 3) [1,2,3,4,5]
--   False
--   
--   
--   
--   >>> all (> 3) [1..]
--   False
--   
--   
--   
--   >>> all (> 3) [4..]
--   * Hangs forever *
--   
all :: Foldable t => (a -> Bool) -> t a -> Bool

-- | notElem is the negation of elem.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> 3 `notElem` []
--   True
--   
--   
--   
--   >>> 3 `notElem` [1,2]
--   True
--   
--   
--   
--   >>> 3 `notElem` [1,2,3,4,5]
--   False
--   
--   
--   For infinite structures, notElem terminates if the value exists
--   at a finite distance from the left side of the structure:
--   
--   
--   >>> 3 `notElem` [1..]
--   False
--   
--   
--   
--   >>> 3 `notElem` ([4..] ++ [3])
--   * Hangs forever *
--   
notElem :: (Foldable t, Eq a) => a -> t a -> Bool
infix 4 `notElem`

-- | Map a function over all the elements of a container and concatenate
--   the resulting lists.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> concatMap (take 3) [[1..], [10..], [100..], [1000..]]
--   [1,2,3,10,11,12,100,101,102,1000,1001,1002]
--   
--   
--   
--   >>> concatMap (take 3) (Just [1..])
--   [1,2,3]
--   
concatMap :: Foldable t => (a -> [b]) -> t a -> [b]

-- | List index (subscript) operator, starting from 0. It is an instance of
--   the more general genericIndex, which takes an index of any
--   integral type.
--   
--   
--   >>> ['a', 'b', 'c'] !! 0
--   'a'
--   
--   >>> ['a', 'b', 'c'] !! 2
--   'c'
--   
--   >>> ['a', 'b', 'c'] !! 3
--   *** Exception: Prelude.!!: index too large
--   
--   >>> ['a', 'b', 'c'] !! (-1)
--   *** Exception: Prelude.!!: negative index
--   
--   
--   WARNING: This function is partial. You can use atMay instead.
(!!) :: HasCallStack => [a] -> Int -> a
infixl 9 !!

-- | zip3 takes three lists and returns a list of triples, analogous
--   to zip. It is capable of list fusion, but it is restricted to
--   its first list argument and its resulting list.
zip3 :: [a] -> [b] -> [c] -> [(a, b, c)]

-- | The zipWith3 function takes a function which combines three
--   elements, as well as three lists and returns a list of the function
--   applied to corresponding elements, analogous to zipWith. It is
--   capable of list fusion, but it is restricted to its first list
--   argument and its resulting list.
--   
--   
--   zipWith3 (,,) xs ys zs == zip3 xs ys zs
--   zipWith3 f [x1,x2,x3..] [y1,y2,y3..] [z1,z2,z3..] == [f x1 y1 z1, f x2 y2 z2, f x3 y3 z3..]
--   
zipWith3 :: (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]

-- | unzip transforms a list of pairs into a list of first
--   components and a list of second components.
--   
--   
--   >>> unzip []
--   ([],[])
--   
--   >>> unzip [(1, 'a'), (2, 'b')]
--   ([1,2],"ab")
--   
unzip :: [(a, b)] -> ([a], [b])

-- | The unzip3 function takes a list of triples and returns three
--   lists, analogous to unzip.
--   
--   
--   >>> unzip3 []
--   ([],[],[])
--   
--   >>> unzip3 [(1, 'a', True), (2, 'b', False)]
--   ([1,2],"ab",[True,False])
--   
unzip3 :: [(a, b, c)] -> ([a], [b], [c])

-- | Convert a character to a string using only printable characters, using
--   Haskell source-language escape conventions. For example:
--   
--   
--   showLitChar '\n' s  =  "\\n" ++ s
--   
showLitChar :: Char -> ShowS

-- | Convert an Int in the range 0..15 to the
--   corresponding single digit Char. This function fails on other
--   inputs, and generates lower-case hexadecimal digits.
intToDigit :: Int -> Char

-- | Formatter for RealFloat values.
formatRealFloat :: RealFloat a => a -> FieldFormatter

-- | 
--   clamp (low, high) a = min high (max a low)
--   
--   
--   Function for ensuring the value a is within the inclusive
--   bounds given by low and high. If it is, a
--   is returned unchanged. The result is otherwise low if a
--   <= low, or high if high <= a.
--   
--   When clamp is used at Double and Float, it has NaN propagating
--   semantics in its second argument. That is, clamp (l,h) NaN =
--   NaN, but clamp (NaN, NaN) x = x.
--   
--   
--   >>> clamp (0, 10) 2
--   2
--   
--   
--   
--   >>> clamp ('a', 'm') 'x'
--   'm'
--   
clamp :: Ord a => (a, a) -> a -> a

-- | Create an MVar which is initially empty.
newEmptyMVar :: IO (MVar a)

-- | Create an MVar which contains the supplied value.
newMVar :: a -> IO (MVar a)

-- | Return the contents of the MVar. If the MVar is
--   currently empty, takeMVar will wait until it is full. After a
--   takeMVar, the MVar is left empty.
--   
--   There are two further important properties of takeMVar:
--   
--   
--   
- takeMVar is single-wakeup. That is, if there are multiple
--   threads blocked in takeMVar, and the MVar becomes full,
--   only one thread will be woken up. The runtime guarantees that the
--   woken thread completes its takeMVar operation.
--   
- When multiple threads are blocked on an MVar, they are
--   woken up in FIFO order. This is useful for providing fairness
--   properties of abstractions built using MVars.
--   
takeMVar :: MVar a -> IO a

-- | Atomically read the contents of an MVar. If the MVar is
--   currently empty, readMVar will wait until it is full.
--   readMVar is guaranteed to receive the next putMVar.
--   
--   readMVar is multiple-wakeup, so when multiple readers are
--   blocked on an MVar, all of them are woken up at the same time.
--   
--   Compatibility note: Prior to base 4.7, readMVar was a
--   combination of takeMVar and putMVar. This mean that in
--   the presence of other threads attempting to putMVar,
--   readMVar could block. Furthermore, readMVar would not
--   receive the next putMVar if there was already a pending thread
--   blocked on takeMVar. The old behavior can be recovered by
--   implementing 'readMVar as follows:
--   
--   
--   readMVar :: MVar a -> IO a
--   readMVar m =
--     mask_ $ do
--       a <- takeMVar m
--       putMVar m a
--       return a
--   
readMVar :: MVar a -> IO a

-- | Put a value into an MVar. If the MVar is currently full,
--   putMVar will wait until it becomes empty.
--   
--   There are two further important properties of putMVar:
--   
--   
--   
- putMVar is single-wakeup. That is, if there are multiple
--   threads blocked in putMVar, and the MVar becomes empty,
--   only one thread will be woken up. The runtime guarantees that the
--   woken thread completes its putMVar operation.
--   
- When multiple threads are blocked on an MVar, they are
--   woken up in FIFO order. This is useful for providing fairness
--   properties of abstractions built using MVars.
--   
putMVar :: MVar a -> a -> IO ()

-- | A non-blocking version of takeMVar. The tryTakeMVar
--   function returns immediately, with Nothing if the MVar
--   was empty, or Just a if the MVar was full with
--   contents a. After tryTakeMVar, the MVar is left
--   empty.
tryTakeMVar :: MVar a -> IO (Maybe a)

-- | A non-blocking version of putMVar. The tryPutMVar
--   function attempts to put the value a into the MVar,
--   returning True if it was successful, or False otherwise.
tryPutMVar :: MVar a -> a -> IO Bool

-- | A non-blocking version of readMVar. The tryReadMVar
--   function returns immediately, with Nothing if the MVar
--   was empty, or Just a if the MVar was full with
--   contents a.
tryReadMVar :: MVar a -> IO (Maybe a)

-- | Check whether a given MVar is empty.
--   
--   Notice that the boolean value returned is just a snapshot of the state
--   of the MVar. By the time you get to react on its result, the MVar may
--   have been filled (or emptied) - so be extremely careful when using
--   this operation. Use tryTakeMVar instead if possible.
isEmptyMVar :: MVar a -> IO Bool
addMVarFinalizer :: MVar a -> IO () -> IO ()

-- | Flipped version of <$>.
--   
--   
--   (<&>) = flip fmap
--   
--   
--   
Examples
--   
--   Apply (+1) to a list, a Just and a Right:
--   
--   
--   >>> Just 2 <&> (+1)
--   Just 3
--   
--   
--   
--   >>> [1,2,3] <&> (+1)
--   [2,3,4]
--   
--   
--   
--   >>> Right 3 <&> (+1)
--   Right 4
--   
(<&>) :: Functor f => f a -> (a -> b) -> f b
infixl 1 <&>

-- | Flipped version of <$.
--   
--   
Examples
--   
--   Replace the contents of a Maybe Int with a
--   constant String:
--   
--   
--   >>> Nothing $> "foo"
--   Nothing
--   
--   >>> Just 90210 $> "foo"
--   Just "foo"
--   
--   
--   Replace the contents of an Either Int
--   Int with a constant String, resulting in an
--   Either Int String:
--   
--   
--   >>> Left 8675309 $> "foo"
--   Left 8675309
--   
--   >>> Right 8675309 $> "foo"
--   Right "foo"
--   
--   
--   Replace each element of a list with a constant String:
--   
--   
--   >>> [1,2,3] $> "foo"
--   ["foo","foo","foo"]
--   
--   
--   Replace the second element of a pair with a constant String:
--   
--   
--   >>> (1,2) $> "foo"
--   (1,"foo")
--   
($>) :: Functor f => f a -> b -> f b
infixl 4 $>

-- | void value discards or ignores the result of
--   evaluation, such as the return value of an IO action.
--   
--   
Examples
--   
--   Replace the contents of a Maybe Int with unit:
--   
--   
--   >>> void Nothing
--   Nothing
--   
--   >>> void (Just 3)
--   Just ()
--   
--   
--   Replace the contents of an Either Int
--   Int with unit, resulting in an Either
--   Int ():
--   
--   
--   >>> void (Left 8675309)
--   Left 8675309
--   
--   >>> void (Right 8675309)
--   Right ()
--   
--   
--   Replace every element of a list with unit:
--   
--   
--   >>> void [1,2,3]
--   [(),(),()]
--   
--   
--   Replace the second element of a pair with unit:
--   
--   
--   >>> void (1,2)
--   (1,())
--   
--   
--   Discard the result of an IO action:
--   
--   
--   >>> mapM print [1,2]
--   1
--   2
--   [(),()]
--   
--   >>> void $ mapM print [1,2]
--   1
--   2
--   
void :: Functor f => f a -> f ()

-- | The Unicode general category of the character. This relies on the
--   Enum instance of GeneralCategory, which must remain in
--   the same order as the categories are presented in the Unicode
--   standard.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> generalCategory 'a'
--   LowercaseLetter
--   
--   >>> generalCategory 'A'
--   UppercaseLetter
--   
--   >>> generalCategory '0'
--   DecimalNumber
--   
--   >>> generalCategory '%'
--   OtherPunctuation
--   
--   >>> generalCategory '♥'
--   OtherSymbol
--   
--   >>> generalCategory '\31'
--   Control
--   
--   >>> generalCategory ' '
--   Space
--   
generalCategory :: Char -> GeneralCategory

-- | Selects the first 128 characters of the Unicode character set,
--   corresponding to the ASCII character set.
isAscii :: Char -> Bool

-- | Selects the first 256 characters of the Unicode character set,
--   corresponding to the ISO 8859-1 (Latin-1) character set.
isLatin1 :: Char -> Bool

-- | Selects ASCII lower-case letters, i.e. characters satisfying both
--   isAscii and isLower.
isAsciiLower :: Char -> Bool

-- | Selects ASCII upper-case letters, i.e. characters satisfying both
--   isAscii and isUpper.
isAsciiUpper :: Char -> Bool

-- | Selects control characters, which are the non-printing characters of
--   the Latin-1 subset of Unicode.
isControl :: Char -> Bool

-- | Selects printable Unicode characters (letters, numbers, marks,
--   punctuation, symbols and spaces).
isPrint :: Char -> Bool

-- | Returns True for any Unicode space character, and the control
--   characters \t, \n, \r, \f,
--   \v.
isSpace :: Char -> Bool

-- | Selects upper-case or title-case alphabetic Unicode characters
--   (letters). Title case is used by a small number of letter ligatures
--   like the single-character form of Lj.
--   
--   Note: this predicate does not work for letter-like
--   characters such as: 'Ⓐ' (U+24B6 circled Latin
--   capital letter A) and 'Ⅳ' (U+2163 Roman numeral
--   four). This is due to selecting only characters with the
--   GeneralCategory UppercaseLetter or
--   TitlecaseLetter.
--   
--   See isUpperCase for a more intuitive predicate. Note that
--   unlike isUpperCase, isUpper does select
--   title-case characters such as 'ǅ' (U+01C5
--   Latin capital letter d with small letter z with caron) or 'ᾯ'
--   (U+1FAF Greek capital letter omega with dasia and perispomeni
--   and prosgegrammeni).
isUpper :: Char -> Bool

-- | Selects upper-case Unicode letter-like characters.
--   
--   Note: this predicate selects characters with the Unicode
--   property Uppercase, which include letter-like characters such
--   as: 'Ⓐ' (U+24B6 circled Latin capital letter A) and
--   'Ⅳ' (U+2163 Roman numeral four).
--   
--   See isUpper for the legacy predicate. Note that unlike
--   isUpperCase, isUpper does select title-case
--   characters such as 'ǅ' (U+01C5 Latin capital letter
--   d with small letter z with caron) or 'ᾯ' (U+1FAF
--   Greek capital letter omega with dasia and perispomeni and
--   prosgegrammeni).
isUpperCase :: Char -> Bool

-- | Selects lower-case alphabetic Unicode characters (letters).
--   
--   Note: this predicate does not work for letter-like
--   characters such as: 'ⓐ' (U+24D0 circled Latin small
--   letter a) and 'ⅳ' (U+2173 small Roman numeral four).
--   This is due to selecting only characters with the
--   GeneralCategory LowercaseLetter.
--   
--   See isLowerCase for a more intuitive predicate.
isLower :: Char -> Bool

-- | Selects lower-case Unicode letter-like characters.
--   
--   Note: this predicate selects characters with the Unicode
--   property Lowercase, which includes letter-like characters
--   such as: 'ⓐ' (U+24D0 circled Latin small letter a)
--   and 'ⅳ' (U+2173 small Roman numeral four).
--   
--   See isLower for the legacy predicate.
isLowerCase :: Char -> Bool

-- | Selects alphabetic or numeric Unicode characters.
--   
--   Note that numeric digits outside the ASCII range, as well as numeric
--   characters which aren't digits, are selected by this function but not
--   by isDigit. Such characters may be part of identifiers but are
--   not used by the printer and reader to represent numbers.
isAlphaNum :: Char -> Bool

-- | Selects ASCII digits, i.e. '0'..'9'.
isDigit :: Char -> Bool

-- | Selects ASCII octal digits, i.e. '0'..'7'.
isOctDigit :: Char -> Bool

-- | Selects ASCII hexadecimal digits, i.e. '0'..'9',
--   'a'..'f', 'A'..'F'.
isHexDigit :: Char -> Bool

-- | Selects Unicode punctuation characters, including various kinds of
--   connectors, brackets and quotes.
--   
--   This function returns True if its argument has one of the
--   following GeneralCategorys, or False otherwise:
--   
--   
--   
- ConnectorPunctuation
--   
- DashPunctuation
--   
- OpenPunctuation
--   
- ClosePunctuation
--   
- InitialQuote
--   
- FinalQuote
--   
- OtherPunctuation
--   
--   
--   These classes are defined in the Unicode Character Database,
--   part of the Unicode standard. The same document defines what is and is
--   not a "Punctuation".
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> isPunctuation 'a'
--   False
--   
--   >>> isPunctuation '7'
--   False
--   
--   >>> isPunctuation '♥'
--   False
--   
--   >>> isPunctuation '"'
--   True
--   
--   >>> isPunctuation '?'
--   True
--   
--   >>> isPunctuation '—'
--   True
--   
isPunctuation :: Char -> Bool

-- | Selects Unicode symbol characters, including mathematical and currency
--   symbols.
--   
--   This function returns True if its argument has one of the
--   following GeneralCategorys, or False otherwise:
--   
--   
--   
- MathSymbol
--   
- CurrencySymbol
--   
- ModifierSymbol
--   
- OtherSymbol
--   
--   
--   These classes are defined in the Unicode Character Database,
--   part of the Unicode standard. The same document defines what is and is
--   not a "Symbol".
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> isSymbol 'a'
--   False
--   
--   >>> isSymbol '6'
--   False
--   
--   >>> isSymbol '='
--   True
--   
--   
--   The definition of "math symbol" may be a little counter-intuitive
--   depending on one's background:
--   
--   
--   >>> isSymbol '+'
--   True
--   
--   >>> isSymbol '-'
--   False
--   
isSymbol :: Char -> Bool

-- | Convert a letter to the corresponding title-case or upper-case letter,
--   if any. (Title case differs from upper case only for a small number of
--   ligature letters.) Any other character is returned unchanged.
toTitle :: Char -> Char

-- | One or none.
--   
--   It is useful for modelling any computation that is allowed to fail.
--   
--   
Examples
--   
--   Using the Alternative instance of Control.Monad.Except,
--   the following functions:
--   
--   
--   >>> import Control.Monad.Except
--   
--   
--   
--   >>> canFail = throwError "it failed" :: Except String Int
--   
--   >>> final = return 42                :: Except String Int
--   
--   
--   Can be combined by allowing the first function to fail:
--   
--   
--   >>> runExcept $ canFail *> final
--   Left "it failed"
--   
--   >>> runExcept $ optional canFail *> final
--   Right 42
--   
optional :: Alternative f => f a -> f (Maybe a)

-- | Read a string representation of a character, using Haskell
--   source-language escape conventions. For example:
--   
--   
--   lexLitChar  "\\nHello"  =  [("\\n", "Hello")]
--   
lexLitChar :: ReadS String

-- | Read a string representation of a character, using Haskell
--   source-language escape conventions, and convert it to the character
--   that it encodes. For example:
--   
--   
--   readLitChar "\\nHello"  =  [('\n', "Hello")]
--   
readLitChar :: ReadS Char

-- | Returns the ThreadId of the calling thread (GHC only).
myThreadId :: IO ThreadId

-- | Case analysis for the Either type. If the value is
--   Left a, apply the first function to a; if it
--   is Right b, apply the second function to b.
--   
--   
Examples
--   
--   We create two values of type Either String
--   Int, one using the Left constructor and another
--   using the Right constructor. Then we apply "either" the
--   length function (if we have a String) or the "times-two"
--   function (if we have an Int):
--   
--   
--   >>> let s = Left "foo" :: Either String Int
--   
--   >>> let n = Right 3 :: Either String Int
--   
--   >>> either length (*2) s
--   3
--   
--   >>> either length (*2) n
--   6
--   
either :: (a -> c) -> (b -> c) -> Either a b -> c

-- | Extracts from a list of Either all the Left elements.
--   All the Left elements are extracted in order.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> let list = [ Left "foo", Right 3, Left "bar", Right 7, Left "baz" ]
--   
--   >>> lefts list
--   ["foo","bar","baz"]
--   
lefts :: [Either a b] -> [a]

-- | Extracts from a list of Either all the Right elements.
--   All the Right elements are extracted in order.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> let list = [ Left "foo", Right 3, Left "bar", Right 7, Left "baz" ]
--   
--   >>> rights list
--   [3,7]
--   
rights :: [Either a b] -> [b]

-- | Partitions a list of Either into two lists. All the Left
--   elements are extracted, in order, to the first component of the
--   output. Similarly the Right elements are extracted to the
--   second component of the output.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> let list = [ Left "foo", Right 3, Left "bar", Right 7, Left "baz" ]
--   
--   >>> partitionEithers list
--   (["foo","bar","baz"],[3,7])
--   
--   
--   The pair returned by partitionEithers x should be the
--   same pair as (lefts x, rights x):
--   
--   
--   >>> let list = [ Left "foo", Right 3, Left "bar", Right 7, Left "baz" ]
--   
--   >>> partitionEithers list == (lefts list, rights list)
--   True
--   
partitionEithers :: [Either a b] -> ([a], [b])

-- | Return True if the given value is a Left-value,
--   False otherwise.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> isLeft (Left "foo")
--   True
--   
--   >>> isLeft (Right 3)
--   False
--   
--   
--   Assuming a Left value signifies some sort of error, we can use
--   isLeft to write a very simple error-reporting function that
--   does absolutely nothing in the case of success, and outputs "ERROR" if
--   any error occurred.
--   
--   This example shows how isLeft might be used to avoid pattern
--   matching when one does not care about the value contained in the
--   constructor:
--   
--   
--   >>> import Control.Monad ( when )
--   
--   >>> let report e = when (isLeft e) $ putStrLn "ERROR"
--   
--   >>> report (Right 1)
--   
--   >>> report (Left "parse error")
--   ERROR
--   
isLeft :: Either a b -> Bool

-- | Return True if the given value is a Right-value,
--   False otherwise.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> isRight (Left "foo")
--   False
--   
--   >>> isRight (Right 3)
--   True
--   
--   
--   Assuming a Left value signifies some sort of error, we can use
--   isRight to write a very simple reporting function that only
--   outputs "SUCCESS" when a computation has succeeded.
--   
--   This example shows how isRight might be used to avoid pattern
--   matching when one does not care about the value contained in the
--   constructor:
--   
--   
--   >>> import Control.Monad ( when )
--   
--   >>> let report e = when (isRight e) $ putStrLn "SUCCESS"
--   
--   >>> report (Left "parse error")
--   
--   >>> report (Right 1)
--   SUCCESS
--   
isRight :: Either a b -> Bool

-- | Return the contents of a Left-value or a default value
--   otherwise.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> fromLeft 1 (Left 3)
--   3
--   
--   >>> fromLeft 1 (Right "foo")
--   1
--   
fromLeft :: a -> Either a b -> a

-- | Return the contents of a Right-value or a default value
--   otherwise.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> fromRight 1 (Right 3)
--   3
--   
--   >>> fromRight 1 (Left "foo")
--   1
--   
fromRight :: b -> Either a b -> b

-- | 
--   comparing p x y = compare (p x) (p y)
--   
--   
--   Useful combinator for use in conjunction with the xxxBy
--   family of functions from Data.List, for example:
--   
--   
--   ... sortBy (comparing fst) ...
--   
comparing :: Ord a => (b -> a) -> b -> b -> Ordering

-- | Convert a single digit Char to the corresponding Int.
--   This function fails unless its argument satisfies isHexDigit,
--   but recognises both upper- and lower-case hexadecimal digits (that is,
--   '0'..'9', 'a'..'f',
--   'A'..'F').
--   
--   
Examples
--   
--   Characters '0' through '9' are converted properly to
--   0..9:
--   
--   
--   >>> map digitToInt ['0'..'9']
--   [0,1,2,3,4,5,6,7,8,9]
--   
--   
--   Both upper- and lower-case 'A' through 'F' are
--   converted as well, to 10..15.
--   
--   
--   >>> map digitToInt ['a'..'f']
--   [10,11,12,13,14,15]
--   
--   >>> map digitToInt ['A'..'F']
--   [10,11,12,13,14,15]
--   
--   
--   Anything else throws an exception:
--   
--   
--   >>> digitToInt 'G'
--   *** Exception: Char.digitToInt: not a digit 'G'
--   
--   >>> digitToInt '♥'
--   *** Exception: Char.digitToInt: not a digit '\9829'
--   
digitToInt :: Char -> Int

-- | Selects Unicode mark characters, for example accents and the like,
--   which combine with preceding characters.
--   
--   This function returns True if its argument has one of the
--   following GeneralCategorys, or False otherwise:
--   
--   
--   
- NonSpacingMark
--   
- SpacingCombiningMark
--   
- EnclosingMark
--   
--   
--   These classes are defined in the Unicode Character Database,
--   part of the Unicode standard. The same document defines what is and is
--   not a "Mark".
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> isMark 'a'
--   False
--   
--   >>> isMark '0'
--   False
--   
--   
--   Combining marks such as accent characters usually need to follow
--   another character before they become printable:
--   
--   
--   >>> map isMark "ò"
--   [False,True]
--   
--   
--   Puns are not necessarily supported:
--   
--   
--   >>> isMark '✓'
--   False
--   
isMark :: Char -> Bool

-- | Selects Unicode numeric characters, including digits from various
--   scripts, Roman numerals, et cetera.
--   
--   This function returns True if its argument has one of the
--   following GeneralCategorys, or False otherwise:
--   
--   
--   
- DecimalNumber
--   
- LetterNumber
--   
- OtherNumber
--   
--   
--   These classes are defined in the Unicode Character Database,
--   part of the Unicode standard. The same document defines what is and is
--   not a "Number".
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> isNumber 'a'
--   False
--   
--   >>> isNumber '%'
--   False
--   
--   >>> isNumber '3'
--   True
--   
--   
--   ASCII '0' through '9' are all numbers:
--   
--   
--   >>> and $ map isNumber ['0'..'9']
--   True
--   
--   
--   Unicode Roman numerals are "numbers" as well:
--   
--   
--   >>> isNumber 'Ⅸ'
--   True
--   
isNumber :: Char -> Bool

-- | Selects Unicode space and separator characters.
--   
--   This function returns True if its argument has one of the
--   following GeneralCategorys, or False otherwise:
--   
--   
--   
- Space
--   
- LineSeparator
--   
- ParagraphSeparator
--   
--   
--   These classes are defined in the Unicode Character Database,
--   part of the Unicode standard. The same document defines what is and is
--   not a "Separator".
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> isSeparator 'a'
--   False
--   
--   >>> isSeparator '6'
--   False
--   
--   >>> isSeparator ' '
--   True
--   
--   
--   Warning: newlines and tab characters are not considered separators.
--   
--   
--   >>> isSeparator '\n'
--   False
--   
--   >>> isSeparator '\t'
--   False
--   
--   
--   But some more exotic characters are (like HTML's &nbsp;):
--   
--   
--   >>> isSeparator '\160'
--   True
--   
isSeparator :: Char -> Bool

-- | Map each element of a structure to a monadic action, evaluate these
--   actions from left to right, and ignore the results. For a version that
--   doesn't ignore the results see mapM.
--   
--   mapM_ is just like traverse_, but specialised to monadic
--   actions.
mapM_ :: (Foldable t, Monad m) => (a -> m b) -> t a -> m ()

-- | forM_ is mapM_ with its arguments flipped. For a version
--   that doesn't ignore the results see forM.
--   
--   forM_ is just like for_, but specialised to monadic
--   actions.
forM_ :: (Foldable t, Monad m) => t a -> (a -> m b) -> m ()

-- | Evaluate each monadic action in the structure from left to right, and
--   ignore the results. For a version that doesn't ignore the results see
--   sequence.
--   
--   sequence_ is just like sequenceA_, but specialised to
--   monadic actions.
sequence_ :: (Foldable t, Monad m) => t (m a) -> m ()

-- | The sum of a collection of actions using (<|>),
--   generalizing concat.
--   
--   asum is just like msum, but generalised to
--   Alternative.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> asum [Just "Hello", Nothing, Just "World"]
--   Just "Hello"
--   
asum :: (Foldable t, Alternative f) => t (f a) -> f a

-- | The sum of a collection of actions using (<|>),
--   generalizing concat.
--   
--   msum is just like asum, but specialised to
--   MonadPlus.
--   
--   
Examples
--   
--   Basic usage, using the MonadPlus instance for Maybe:
--   
--   
--   >>> msum [Just "Hello", Nothing, Just "World"]
--   Just "Hello"
--   
msum :: (Foldable t, MonadPlus m) => t (m a) -> m a

-- | The find function takes a predicate and a structure and returns
--   the leftmost element of the structure matching the predicate, or
--   Nothing if there is no such element.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> find (> 42) [0, 5..]
--   Just 45
--   
--   
--   
--   >>> find (> 12) [1..7]
--   Nothing
--   
find :: Foldable t => (a -> Bool) -> t a -> Maybe a

-- | The dropWhileEnd function drops the largest suffix of a list in
--   which the given predicate holds for all elements. For example:
--   
--   
--   >>> dropWhileEnd isSpace "foo\n"
--   "foo"
--   
--   
--   
--   >>> dropWhileEnd isSpace "foo bar"
--   "foo bar"
--   
--   
--   
--   dropWhileEnd isSpace ("foo\n" ++ undefined) == "foo" ++ undefined
--   
dropWhileEnd :: (a -> Bool) -> [a] -> [a]

-- | <math>. The stripPrefix function drops the given prefix
--   from a list. It returns Nothing if the list did not start with
--   the prefix given, or Just the list after the prefix, if it
--   does.
--   
--   
--   >>> stripPrefix "foo" "foobar"
--   Just "bar"
--   
--   
--   
--   >>> stripPrefix "foo" "foo"
--   Just ""
--   
--   
--   
--   >>> stripPrefix "foo" "barfoo"
--   Nothing
--   
--   
--   
--   >>> stripPrefix "foo" "barfoobaz"
--   Nothing
--   
stripPrefix :: Eq a => [a] -> [a] -> Maybe [a]

-- | The elemIndex function returns the index of the first element
--   in the given list which is equal (by ==) to the query element,
--   or Nothing if there is no such element. For the result to be
--   Nothing, the list must be finite.
--   
--   
--   >>> elemIndex 4 [0..]
--   Just 4
--   
elemIndex :: Eq a => a -> [a] -> Maybe Int

-- | The elemIndices function extends elemIndex, by returning
--   the indices of all elements equal to the query element, in ascending
--   order.
--   
--   
--   >>> elemIndices 'o' "Hello World"
--   [4,7]
--   
elemIndices :: Eq a => a -> [a] -> [Int]

-- | The findIndex function takes a predicate and a list and returns
--   the index of the first element in the list satisfying the predicate,
--   or Nothing if there is no such element. For the result to be
--   Nothing, the list must be finite.
--   
--   
--   >>> findIndex isSpace "Hello World!"
--   Just 5
--   
findIndex :: (a -> Bool) -> [a] -> Maybe Int

-- | The findIndices function extends findIndex, by returning
--   the indices of all elements satisfying the predicate, in ascending
--   order.
--   
--   
--   >>> findIndices (`elem` "aeiou") "Hello World!"
--   [1,4,7]
--   
findIndices :: (a -> Bool) -> [a] -> [Int]

-- | <math>. The isPrefixOf function takes two lists and
--   returns True iff the first list is a prefix of the second.
--   
--   
--   >>> "Hello" `isPrefixOf` "Hello World!"
--   True
--   
--   >>> "Hello" `isPrefixOf` "Wello Horld!"
--   False
--   
--   
--   For the result to be True, the first list must be finite;
--   False, however, results from any mismatch:
--   
--   
--   >>> [0..] `isPrefixOf` [1..]
--   False
--   
--   >>> [0..] `isPrefixOf` [0..99]
--   False
--   
--   >>> [0..99] `isPrefixOf` [0..]
--   True
--   
--   >>> [0..] `isPrefixOf` [0..]
--   * Hangs forever *
--   
isPrefixOf :: Eq a => [a] -> [a] -> Bool

-- | The isSuffixOf function takes two lists and returns True
--   iff the first list is a suffix of the second.
--   
--   
--   >>> "ld!" `isSuffixOf` "Hello World!"
--   True
--   
--   >>> "World" `isSuffixOf` "Hello World!"
--   False
--   
--   
--   The second list must be finite; however the first list may be
--   infinite:
--   
--   
--   >>> [0..] `isSuffixOf` [0..99]
--   False
--   
--   >>> [0..99] `isSuffixOf` [0..]
--   * Hangs forever *
--   
isSuffixOf :: Eq a => [a] -> [a] -> Bool

-- | The isInfixOf function takes two lists and returns True
--   iff the first list is contained, wholly and intact, anywhere within
--   the second.
--   
--   
--   >>> isInfixOf "Haskell" "I really like Haskell."
--   True
--   
--   >>> isInfixOf "Ial" "I really like Haskell."
--   False
--   
--   
--   For the result to be True, the first list must be finite; for
--   the result to be False, the second list must be finite:
--   
--   
--   >>> [20..50] `isInfixOf` [0..]
--   True
--   
--   >>> [0..] `isInfixOf` [20..50]
--   False
--   
--   >>> [0..] `isInfixOf` [0..]
--   * Hangs forever *
--   
isInfixOf :: Eq a => [a] -> [a] -> Bool

-- | <math>. The nub function removes duplicate elements from
--   a list. In particular, it keeps only the first occurrence of each
--   element. (The name nub means `essence'.) It is a special case
--   of nubBy, which allows the programmer to supply their own
--   equality test.
--   
--   
--   >>> nub [1,2,3,4,3,2,1,2,4,3,5]
--   [1,2,3,4,5]
--   
--   
--   If the order of outputs does not matter and there exists instance
--   Ord a, it's faster to use map
--   Data.List.NonEmpty.head .
--   Data.List.NonEmpty.group . sort, which takes
--   only <math> time.
nub :: Eq a => [a] -> [a]

-- | The nubBy function behaves just like nub, except it uses
--   a user-supplied equality predicate instead of the overloaded ==
--   function.
--   
--   
--   >>> nubBy (\x y -> mod x 3 == mod y 3) [1,2,4,5,6]
--   [1,2,6]
--   
nubBy :: (a -> a -> Bool) -> [a] -> [a]

-- | <math>. The deleteBy function behaves like delete,
--   but takes a user-supplied equality predicate.
--   
--   
--   >>> deleteBy (<=) 4 [1..10]
--   [1,2,3,5,6,7,8,9,10]
--   
deleteBy :: (a -> a -> Bool) -> a -> [a] -> [a]

-- | The \\ function is list difference (non-associative). In the
--   result of xs \\ ys, the first occurrence of
--   each element of ys in turn (if any) has been removed from
--   xs. Thus (xs ++ ys) \\ xs == ys.
--   
--   
--   >>> "Hello World!" \\ "ell W"
--   "Hoorld!"
--   
--   
--   It is a special case of deleteFirstsBy, which allows the
--   programmer to supply their own equality test.
--   
--   The second list must be finite, but the first may be infinite.
--   
--   
--   >>> take 5 ([0..] \\ [2..4])
--   [0,1,5,6,7]
--   
--   >>> take 5 ([0..] \\ [2..])
--   * Hangs forever *
--   
(\\) :: Eq a => [a] -> [a] -> [a]
infix 5 \\

-- | The unionBy function is the non-overloaded version of
--   union. Both arguments may be infinite.
unionBy :: (a -> a -> Bool) -> [a] -> [a] -> [a]

-- | The intersect function takes the list intersection of two
--   lists. It is a special case of intersectBy, which allows the
--   programmer to supply their own equality test. For example,
--   
--   
--   >>> [1,2,3,4] `intersect` [2,4,6,8]
--   [2,4]
--   
--   
--   If equal elements are present in both lists, an element from the first
--   list will be used, and all duplicates from the second list quashed:
--   
--   
--   >>> import Data.Semigroup
--   
--   >>> intersect [Arg () "dog"] [Arg () "cow", Arg () "cat"]
--   [Arg () "dog"]
--   
--   
--   However if the first list contains duplicates, so will the result.
--   
--   
--   >>> "coot" `intersect` "heron"
--   "oo"
--   
--   >>> "heron" `intersect` "coot"
--   "o"
--   
--   
--   If the second list is infinite, intersect either hangs or
--   returns its first argument in full. Otherwise if the first list is
--   infinite, intersect might be productive:
--   
--   
--   >>> intersect [100..] [0..]
--   [100,101,102,103...
--   
--   >>> intersect [0] [1..]
--   * Hangs forever *
--   
--   >>> intersect [1..] [0]
--   * Hangs forever *
--   
--   >>> intersect (cycle [1..3]) [2]
--   [2,2,2,2...
--   
intersect :: Eq a => [a] -> [a] -> [a]

-- | The intersectBy function is the non-overloaded version of
--   intersect. It is productive for infinite arguments only if the
--   first one is a subset of the second.
intersectBy :: (a -> a -> Bool) -> [a] -> [a] -> [a]

-- | <math>. The intersperse function takes an element and a
--   list and `intersperses' that element between the elements of the list.
--   For example,
--   
--   
--   >>> intersperse ',' "abcde"
--   "a,b,c,d,e"
--   
intersperse :: a -> [a] -> [a]

-- | intercalate xs xss is equivalent to (concat
--   (intersperse xs xss)). It inserts the list xs in
--   between the lists in xss and concatenates the result.
--   
--   
--   >>> intercalate ", " ["Lorem", "ipsum", "dolor"]
--   "Lorem, ipsum, dolor"
--   
intercalate :: [a] -> [[a]] -> [a]

-- | The partition function takes a predicate and a list, and
--   returns the pair of lists of elements which do and do not satisfy the
--   predicate, respectively; i.e.,
--   
--   
--   partition p xs == (filter p xs, filter (not . p) xs)
--   
--   
--   
--   >>> partition (`elem` "aeiou") "Hello World!"
--   ("eoo","Hll Wrld!")
--   
partition :: (a -> Bool) -> [a] -> ([a], [a])

-- | The mapAccumL function behaves like a combination of
--   fmap and foldl; it applies a function to each element of
--   a structure, passing an accumulating parameter from left to right, and
--   returning a final value of this accumulator together with the new
--   structure.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> mapAccumL (\a b -> (a + b, a)) 0 [1..10]
--   (55,[0,1,3,6,10,15,21,28,36,45])
--   
--   
--   
--   >>> mapAccumL (\a b -> (a <> show b, a)) "0" [1..5]
--   ("012345",["0","01","012","0123","01234"])
--   
mapAccumL :: Traversable t => (s -> a -> (s, b)) -> s -> t a -> (s, t b)

-- | The mapAccumR function behaves like a combination of
--   fmap and foldr; it applies a function to each element of
--   a structure, passing an accumulating parameter from right to left, and
--   returning a final value of this accumulator together with the new
--   structure.
--   
--   
Examples
--   
--   Basic usage:
--   
--   
--   >>> mapAccumR (\a b -> (a + b, a)) 0 [1..10]
--   (55,[54,52,49,45,40,34,27,19,10,0])
--   
--   
--   
--   >>> mapAccumR (\a b -> (a <> show b, a)) "0" [1..5]
--   ("054321",["05432","0543","054","05","0"])
--   
mapAccumR :: Traversable t => (s -> a -> (s, b)) -> s -> t a -> (s, t b)

-- | <math>. The non-overloaded version of insert.
insertBy :: (a -> a -> Ordering) -> a -> [a] -> [a]

-- | The zip4 function takes four lists and returns a list of
--   quadruples, analogous to zip. It is capable of list fusion, but
--   it is restricted to its first list argument and its resulting list.
zip4 :: [a] -> [b] -> [c] -> [d] -> [(a, b, c, d)]

-- | The zip5 function takes five lists and returns a list of
--   five-tuples, analogous to zip. It is capable of list fusion,
--   but it is restricted to its first list argument and its resulting
--   list.
zip5 :: [a] -> [b] -> [c] -> [d] -> [e] -> [(a, b, c, d, e)]

-- | The zip6 function takes six lists and returns a list of
--   six-tuples, analogous to zip. It is capable of list fusion, but
--   it is restricted to its first list argument and its resulting list.
zip6 :: [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [(a, b, c, d, e, f)]

-- | The zip7 function takes seven lists and returns a list of
--   seven-tuples, analogous to zip. It is capable of list fusion,
--   but it is restricted to its first list argument and its resulting
--   list.
zip7 :: [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [g] -> [(a, b, c, d, e, f, g)]

-- | The zipWith4 function takes a function which combines four
--   elements, as well as four lists and returns a list of their point-wise
--   combination, analogous to zipWith. It is capable of list
--   fusion, but it is restricted to its first list argument and its
--   resulting list.
zipWith4 :: (a -> b -> c -> d -> e) -> [a] -> [b] -> [c] -> [d] -> [e]

-- | The zipWith5 function takes a function which combines five
--   elements, as well as five lists and returns a list of their point-wise
--   combination, analogous to zipWith. It is capable of list
--   fusion, but it is restricted to its first list argument and its
--   resulting list.
zipWith5 :: (a -> b -> c -> d -> e -> f) -> [a] -> [b] -> [c] -> [d] -> [e] -> [f]

-- | The zipWith6 function takes a function which combines six
--   elements, as well as six lists and returns a list of their point-wise
--   combination, analogous to zipWith. It is capable of list
--   fusion, but it is restricted to its first list argument and its
--   resulting list.
zipWith6 :: (a -> b -> c -> d -> e -> f -> g) -> [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [g]

-- | The zipWith7 function takes a function which combines seven
--   elements, as well as seven lists and returns a list of their
--   point-wise combination, analogous to zipWith. It is capable of
--   list fusion, but it is restricted to its first list argument and its
--   resulting list.
zipWith7 :: (a -> b -> c -> d -> e -> f -> g -> h) -> [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [g] -> [h]

-- | The unzip4 function takes a list of quadruples and returns four
--   lists, analogous to unzip.
unzip4 :: [(a, b, c, d)] -> ([a], [b], [c], [d])

-- | The unzip5 function takes a list of five-tuples and returns
--   five lists, analogous to unzip.
unzip5 :: [(a, b, c, d, e)] -> ([a], [b], [c], [d], [e])

-- | The unzip6 function takes a list of six-tuples and returns six
--   lists, analogous to unzip.
unzip6 :: [(a, b, c, d, e, f)] -> ([a], [b], [c], [d], [e], [f])

-- | The unzip7 function takes a list of seven-tuples and returns
--   seven lists, analogous to unzip.
unzip7 :: [(a, b, c, d, e, f, g)] -> ([a], [b], [c], [d], [e], [f], [g])

-- | The deleteFirstsBy function takes a predicate and two lists and
--   returns the first list with the first occurrence of each element of
--   the second list removed. This is the non-overloaded version of
--   (\\).
--   
--   The second list must be finite, but the first may be infinite.
deleteFirstsBy :: (a -> a -> Bool) -> [a] -> [a] -> [a]

-- | The inits function returns all initial segments of the
--   argument, shortest first. For example,
--   
--   
--   >>> inits "abc"
--   ["","a","ab","abc"]
--   
--   
--   Note that inits has the following strictness property:
--   inits (xs ++ _|_) = inits xs ++ _|_
--   
--   In particular, inits _|_ = [] : _|_
--   
--   inits is semantically equivalent to map
--   reverse . scanl (flip (:)) [], but under the
--   hood uses a queue to amortize costs of reverse.
inits :: [a] -> [[a]]

-- | <math>. The tails function returns all final segments of
--   the argument, longest first. For example,
--   
--   
--   >>> tails "abc"
--   ["abc","bc","c",""]
--   
--   
--   Note that tails has the following strictness property:
--   tails _|_ = _|_ : _|_
tails :: [a] -> [[a]]

-- | The subsequences function returns the list of all subsequences
--   of the argument.
--   
--   
--   >>> subsequences "abc"
--   ["","a","b","ab","c","ac","bc","abc"]
--   
--   
--   This function is productive on infinite inputs:
--   
--   
--   >>> take 8 $ subsequences ['a'..]
--   ["","a","b","ab","c","ac","bc","abc"]
--   
subsequences :: [a] -> [[a]]

-- | The permutations function returns the list of all permutations
--   of the argument.
--   
--   
--   >>> permutations "abc"
--   ["abc","bac","cba","bca","cab","acb"]
--   
--   
--   The permutations function is maximally lazy: for each
--   n, the value of permutations xs starts with
--   those permutations that permute take n xs and keep
--   drop n xs.
--   
--   This function is productive on infinite inputs:
--   
--   
--   >>> take 6 $ map (take 3) $ permutations ['a'..]
--   ["abc","bac","cba","bca","cab","acb"]
--   
--   
--   Note that the order of permutations is not lexicographic. It satisfies
--   the following property:
--   
--   
--   map (take n) (take (product [1..n]) (permutations ([1..n] ++ undefined))) == permutations [1..n]
--   
permutations :: [a] -> [[a]]

-- | The sort function implements a stable sorting algorithm. It is
--   a special case of sortBy, which allows the programmer to supply
--   their own comparison function.
--   
--   Elements are arranged from lowest to highest, keeping duplicates in
--   the order they appeared in the input.
--   
--   
--   >>> sort [1,6,4,3,2,5]
--   [1,2,3,4,5,6]
--   
--   
--   The argument must be finite.
sort :: Ord a => [a] -> [a]

-- | Splits the argument into a list of lines stripped of their
--   terminating \n characters. The \n terminator is
--   optional in a final non-empty line of the argument string.
--   
--   For example:
--   
--   
--   >>> lines ""           -- empty input contains no lines
--   []
--   
--   >>> lines "\n"         -- single empty line
--   [""]
--   
--   >>> lines "one"        -- single unterminated line
--   ["one"]
--   
--   >>> lines "one\n"      -- single non-empty line
--   ["one"]
--   
--   >>> lines "one\n\n"    -- second line is empty
--   ["one",""]
--   
--   >>> lines "one\ntwo"   -- second line is unterminated
--   ["one","two"]
--   
--   >>> lines "one\ntwo\n" -- two non-empty lines
--   ["one","two"]
--   
--   
--   When the argument string is empty, or ends in a \n character,
--   it can be recovered by passing the result of lines to the
--   unlines function. Otherwise, unlines appends the missing
--   terminating \n. This makes unlines . lines
--   idempotent:
--   
--   
--   (unlines . lines) . (unlines . lines) = (unlines . lines)
--   
lines :: String -> [String]

-- | Appends a \n character to each input string, then
--   concatenates the results. Equivalent to foldMap (s ->
--   s ++ "\n").
--   
--   
--   >>> unlines ["Hello", "World", "!"]
--   "Hello\nWorld\n!\n"
--   
--   
--   Note that unlines . lines /=
--   id when the input is not \n-terminated:
--   
--   
--   >>> unlines . lines $ "foo\nbar"
--   "foo\nbar\n"
--   
unlines :: [String] -> String

-- | words breaks a string up into a list of words, which were
--   delimited by white space (as defined by isSpace). This function
--   trims any white spaces at the beginning and at the end.
--   
--   
--   >>> words "Lorem ipsum\ndolor"
--   ["Lorem","ipsum","dolor"]
--   
--   >>> words " foo bar "
--   ["foo","bar"]
--   
words :: String -> [String]

-- | unwords joins words with separating spaces (U+0020 SPACE).
--   
--   
--   >>> unwords ["Lorem", "ipsum", "dolor"]
--   "Lorem ipsum dolor"
--   
--   
--   unwords is neither left nor right inverse of words:
--   
--   
--   >>> words (unwords [" "])
--   []
--   
--   >>> unwords (words "foo\nbar")
--   "foo bar"
--   
unwords :: [String] -> String

-- | Construct an IOException value with a string describing the
--   error. The fail method of the IO instance of the
--   Monad class raises a userError, thus:
--   
--   
--   instance Monad IO where
--     ...
--     fail s = ioError (userError s)
--   
userError :: String -> IOError
close :: CliOpts -> Journal -> IO ()

-- | The native newline representation for the current platform: LF
--   on Unix systems, CRLF on Windows.
nativeNewline :: Newline

-- | Map '\r\n' into '\n' on input, and '\n' to
--   the native newline representation on output. This mode can be used on
--   any platform, and works with text files using any newline convention.
--   The downside is that readFile >>= writeFile might yield
--   a different file.
--   
--   
--   universalNewlineMode  = NewlineMode { inputNL  = CRLF,
--                                         outputNL = nativeNewline }
--   
universalNewlineMode :: NewlineMode

-- | Use the native newline representation on both input and output
--   
--   
--   nativeNewlineMode  = NewlineMode { inputNL  = nativeNewline
--                                      outputNL = nativeNewline }
--   
nativeNewlineMode :: NewlineMode

-- | Do no newline translation at all.
--   
--   
--   noNewlineTranslation  = NewlineMode { inputNL  = LF, outputNL = LF }
--   
noNewlineTranslation :: NewlineMode

-- | Raise an IOException in the IO monad.
ioError :: IOError -> IO a

-- | Like forkIO, but lets you specify on which capability the
--   thread should run. Unlike a forkIO thread, a thread created by
--   forkOn will stay on the same capability for its entire lifetime
--   (forkIO threads can migrate between capabilities according to
--   the scheduling policy). forkOn is useful for overriding the
--   scheduling policy when you know in advance how best to distribute the
--   threads.
--   
--   The Int argument specifies a capability number (see
--   getNumCapabilities). Typically capabilities correspond to
--   physical processors, but the exact behaviour is
--   implementation-dependent. The value passed to forkOn is
--   interpreted modulo the total number of capabilities as returned by
--   getNumCapabilities.
--   
--   GHC note: the number of capabilities is specified by the +RTS
--   -N option when the program is started. Capabilities can be fixed
--   to actual processor cores with +RTS -qa if the underlying
--   operating system supports that, although in practice this is usually
--   unnecessary (and may actually degrade performance in some cases -
--   experimentation is recommended).
forkOn :: Int -> IO () -> IO ThreadId

-- | Like forkIOWithUnmask, but the child thread is pinned to the
--   given CPU, as with forkOn.
forkOnWithUnmask :: Int -> ((forall a. () => IO a -> IO a) -> IO ()) -> IO ThreadId

-- | Returns the number of Haskell threads that can run truly
--   simultaneously (on separate physical processors) at any given time. To
--   change this value, use setNumCapabilities.
getNumCapabilities :: IO Int

-- | Set the number of Haskell threads that can run truly simultaneously
--   (on separate physical processors) at any given time. The number passed
--   to forkOn is interpreted modulo this value. The initial value
--   is given by the +RTS -N runtime flag.
--   
--   This is also the number of threads that will participate in parallel
--   garbage collection. It is strongly recommended that the number of
--   capabilities is not set larger than the number of physical processor
--   cores, and it may often be beneficial to leave one or more cores free
--   to avoid contention with other processes in the machine.
setNumCapabilities :: Int -> IO ()

-- | The yield action allows (forces, in a co-operative multitasking
--   implementation) a context-switch to any other currently runnable
--   threads (if any), and is occasionally useful when implementing
--   concurrency abstractions.
yield :: IO ()

-- | Returns the number of the capability on which the thread is currently
--   running, and a boolean indicating whether the thread is locked to that
--   capability or not. A thread is locked to a capability if it was
--   created with forkOn.
threadCapability :: ThreadId -> IO (Int, Bool)

-- | Make a weak pointer to a ThreadId. It can be important to do
--   this if you want to hold a reference to a ThreadId while still
--   allowing the thread to receive the BlockedIndefinitely family
--   of exceptions (e.g. BlockedIndefinitelyOnMVar). Holding a
--   normal ThreadId reference will prevent the delivery of
--   BlockedIndefinitely exceptions because the reference could be
--   used as the target of throwTo at any time, which would unblock
--   the thread.
--   
--   Holding a Weak ThreadId, on the other hand, will not prevent
--   the thread from receiving BlockedIndefinitely exceptions. It
--   is still possible to throw an exception to a Weak ThreadId,
--   but the caller must use deRefWeak first to determine whether
--   the thread still exists.
mkWeakThreadId :: ThreadId -> IO (Weak ThreadId)

-- | withMVar is an exception-safe wrapper for operating on the
--   contents of an MVar. This operation is exception-safe: it will
--   replace the original contents of the MVar if an exception is
--   raised (see Control.Exception). However, it is only atomic if
--   there are no other producers for this MVar. In other words, it
--   cannot guarantee that, by the time withMVar gets the chance to
--   write to the MVar, the value of the MVar has not been altered by a
--   write operation from another thread.
withMVar :: MVar a -> (a -> IO b) -> IO b

-- | An exception-safe wrapper for modifying the contents of an
--   MVar. Like withMVar, modifyMVar will replace the
--   original contents of the MVar if an exception is raised during
--   the operation. This function is only atomic if there are no other
--   producers for this MVar. In other words, it cannot guarantee
--   that, by the time modifyMVar_ gets the chance to write to the
--   MVar, the value of the MVar has not been altered by a write operation
--   from another thread.
modifyMVar_ :: MVar a -> (a -> IO a) -> IO ()

-- | Take a value from an MVar, put a new value into the MVar
--   and return the value taken. This function is atomic only if there are
--   no other producers for this MVar. In other words, it cannot
--   guarantee that, by the time swapMVar gets the chance to write
--   to the MVar, the value of the MVar has not been altered by a write
--   operation from another thread.
swapMVar :: MVar a -> a -> IO a

-- | Like withMVar, but the IO action in the second
--   argument is executed with asynchronous exceptions masked.
withMVarMasked :: MVar a -> (a -> IO b) -> IO b

-- | A slight variation on modifyMVar_ that allows a value to be
--   returned (b) in addition to the modified value of the
--   MVar.
modifyMVar :: MVar a -> (a -> IO (a, b)) -> IO b

-- | Like modifyMVar_, but the IO action in the second
--   argument is executed with asynchronous exceptions masked.
modifyMVarMasked_ :: MVar a -> (a -> IO a) -> IO ()

-- | Like modifyMVar, but the IO action in the second
--   argument is executed with asynchronous exceptions masked.
modifyMVarMasked :: MVar a -> (a -> IO (a, b)) -> IO b

-- | Make a Weak pointer to an MVar, using the second
--   argument as a finalizer to run when MVar is garbage-collected
mkWeakMVar :: MVar a -> IO () -> IO (Weak (MVar a))

-- | The construct tryIOError comp exposes IO errors which
--   occur within a computation, and which are not fully handled.
--   
--   Non-I/O exceptions are not caught by this variant; to catch all
--   exceptions, use try from Control.Exception.
tryIOError :: IO a -> IO (Either IOError a)

-- | Construct an IOException of the given type where the second
--   argument describes the error location and the third and fourth
--   argument contain the file handle and file path of the file involved in
--   the error if applicable.
mkIOError :: IOErrorType -> String -> Maybe Handle -> Maybe FilePath -> IOError

-- | An error indicating that an IO operation failed because one of
--   its arguments already exists.
isAlreadyExistsError :: IOError -> Bool

-- | A programmer-defined error value constructed using userError.
isUserError :: IOError -> Bool

-- | An error indicating that the operation failed because the resource
--   vanished. See resourceVanishedErrorType.
isResourceVanishedError :: IOError -> Bool

-- | I/O error where the operation failed because one of its arguments
--   already exists.
alreadyExistsErrorType :: IOErrorType

-- | I/O error where the operation failed because one of its arguments does
--   not exist.
doesNotExistErrorType :: IOErrorType

-- | I/O error where the operation failed because one of its arguments is a
--   single-use resource, which is already being used.
alreadyInUseErrorType :: IOErrorType

-- | I/O error where the operation failed because the device is full.
fullErrorType :: IOErrorType

-- | I/O error where the operation failed because the end of file has been
--   reached.
eofErrorType :: IOErrorType

-- | I/O error where the operation is not possible.
illegalOperationErrorType :: IOErrorType

-- | I/O error where the operation failed because the user does not have
--   sufficient operating system privilege to perform that operation.
permissionErrorType :: IOErrorType

-- | I/O error that is programmer-defined.
userErrorType :: IOErrorType

-- | I/O error where the operation failed because the resource vanished.
--   This happens when, for example, attempting to write to a closed socket
--   or attempting to write to a named pipe that was deleted.
resourceVanishedErrorType :: IOErrorType

-- | I/O error where the operation failed because one of its arguments
--   already exists.
isAlreadyExistsErrorType :: IOErrorType -> Bool

-- | I/O error where the operation failed because one of its arguments does
--   not exist.
isDoesNotExistErrorType :: IOErrorType -> Bool

-- | I/O error where the operation failed because one of its arguments is a
--   single-use resource, which is already being used.
isAlreadyInUseErrorType :: IOErrorType -> Bool

-- | I/O error where the operation failed because the device is full.
isFullErrorType :: IOErrorType -> Bool

-- | I/O error where the operation failed because the end of file has been
--   reached.
isEOFErrorType :: IOErrorType -> Bool

-- | I/O error where the operation is not possible.
isIllegalOperationErrorType :: IOErrorType -> Bool

-- | I/O error where the operation failed because the user does not have
--   sufficient operating system privilege to perform that operation.
isPermissionErrorType :: IOErrorType -> Bool

-- | I/O error that is programmer-defined.
isUserErrorType :: IOErrorType -> Bool

-- | I/O error where the operation failed because the resource vanished.
--   See resourceVanishedErrorType.
isResourceVanishedErrorType :: IOErrorType -> Bool
ioeGetErrorType :: IOError -> IOErrorType
ioeGetErrorString :: IOError -> String
ioeGetLocation :: IOError -> String
ioeGetHandle :: IOError -> Maybe Handle
ioeGetFileName :: IOError -> Maybe FilePath
ioeSetErrorType :: IOError -> IOErrorType -> IOError
ioeSetErrorString :: IOError -> String -> IOError
ioeSetLocation :: IOError -> String -> IOError
ioeSetHandle :: IOError -> Handle -> IOError
ioeSetFileName :: IOError -> FilePath -> IOError

-- | Catch any IOException that occurs in the computation and throw
--   a modified version.
modifyIOError :: (IOError -> IOError) -> IO a -> IO a

-- | Adds a location description and maybe a file path and file handle to
--   an IOException. If any of the file handle or file path is not
--   given the corresponding value in the IOException remains
--   unaltered.
annotateIOError :: IOError -> String -> Maybe Handle -> Maybe FilePath -> IOError

-- | The catchIOError function establishes a handler that receives
--   any IOException raised in the action protected by
--   catchIOError. An IOException is caught by the most
--   recent handler established by one of the exception handling functions.
--   These handlers are not selective: all IOExceptions are caught.
--   Exception propagation must be explicitly provided in a handler by
--   re-raising any unwanted exceptions. For example, in
--   
--   
--   f = catchIOError g (\e -> if IO.isEOFError e then return [] else ioError e)
--   
--   
--   the function f returns [] when an end-of-file
--   exception (cf. isEOFError) occurs in g; otherwise, the
--   exception is propagated to the next outer handler.
--   
--   When an exception propagates outside the main program, the Haskell
--   system prints the associated IOException value and exits the
--   program.
--   
--   Non-I/O exceptions are not caught by this variant; to catch all
--   exceptions, use catch from Control.Exception.
catchIOError :: IO a -> (IOError -> IO a) -> IO a

-- | The UTF-8 Unicode encoding, with a byte-order-mark (BOM; the byte
--   sequence 0xEF 0xBB 0xBF). This encoding behaves like utf8,
--   except that on input, the BOM sequence is ignored at the beginning of
--   the stream, and on output, the BOM sequence is prepended.
--   
--   The byte-order-mark is strictly unnecessary in UTF-8, but is sometimes
--   used to identify the encoding of a file.
utf8_bom :: TextEncoding

-- | The UTF-32 Unicode encoding (a byte-order-mark should be used to
--   indicate endianness).
utf32 :: TextEncoding

-- | The UTF-32 Unicode encoding (big-endian)
utf32be :: TextEncoding

-- | The UTF-32 Unicode encoding (little-endian)
utf32le :: TextEncoding

-- | The UTF-16 Unicode encoding (a byte-order-mark should be used to
--   indicate endianness).
utf16 :: TextEncoding

-- | The UTF-16 Unicode encoding (big-endian)
utf16be :: TextEncoding

-- | The UTF-16 Unicode encoding (little-endian)
utf16le :: TextEncoding

-- | The Latin1 (ISO8859-1) encoding. This encoding maps bytes directly to
--   the first 256 Unicode code points, and is thus not a complete Unicode
--   encoding. An attempt to write a character greater than '\255'
--   to a Handle using the latin1 encoding will result in an
--   error.
latin1 :: TextEncoding

-- | An encoding in which Unicode code points are translated to bytes by
--   taking the code point modulo 256. When decoding, bytes are translated
--   directly into the equivalent code point.
--   
--   This encoding never fails in either direction. However, encoding
--   discards information, so encode followed by decode is not the
--   identity.
char8 :: TextEncoding

-- | The traceIO function outputs the trace message from the IO
--   monad. This sequences the output with respect to other IO actions.
traceIO :: String -> IO ()

-- | Computation hGetChar hdl reads a character from the
--   file or channel managed by hdl, blocking until a character is
--   available.
--   
--   This operation may fail with:
--   
--   
--   
- isEOFError if the end of file has been reached.
--   
hGetChar :: Handle -> IO Char

-- | Computation hGetLine hdl reads a line from the file or
--   channel managed by hdl. hGetLine does not return the
--   newline as part of the result.
--   
--   A line is separated by the newline set with hSetNewlineMode or
--   nativeNewline by default. The read newline character(s) are not
--   returned as part of the result.
--   
--   If hGetLine encounters end-of-file at any point while reading
--   in the middle of a line, it is treated as a line terminator and the
--   (partial) line is returned.
--   
--   This operation may fail with:
--   
--   
--   
- isEOFError if the end of file is encountered when reading
--   the first character of the line.
--   
--   
--   
Examples
--   
--   
--   >>> withFile "/home/user/foo" ReadMode hGetLine >>= putStrLn
--   this is the first line of the file :O
--   
--   
--   
--   >>> withFile "/home/user/bar" ReadMode (replicateM 3 . hGetLine)
--   ["this is the first line","this is the second line","this is the third line"]
--   
hGetLine :: Handle -> IO String

-- | The hGetContents' operation reads all input on the given handle
--   before returning it as a String and closing the handle.
hGetContents' :: Handle -> IO String

-- | Computation hPutChar hdl ch writes the character
--   ch to the file or channel managed by hdl. Characters
--   may be buffered if buffering is enabled for hdl.
--   
--   This operation may fail with:
--   
--   
--   
- isFullError if the device is full; or
--   
- isPermissionError if another system resource limit would be
--   exceeded.
--   
hPutChar :: Handle -> Char -> IO ()

-- | Computation hPutStr hdl s writes the string s
--   to the file or channel managed by hdl.
--   
--   This operation may fail with:
--   
--   
--   
- isFullError if the device is full; or
--   
- isPermissionError if another system resource limit would be
--   exceeded.
--   
hPutStr :: Handle -> String -> IO ()

-- | The same as hPutStr, but adds a newline character.
hPutStrLn :: Handle -> String -> IO ()
hPutBufNonBlocking :: Handle -> Ptr a -> Int -> IO Int

-- | hGetBufSome hdl buf count reads data from the handle
--   hdl into the buffer buf. If there is any data
--   available to read, then hGetBufSome returns it immediately; it
--   only blocks if there is no data to be read.
--   
--   It returns the number of bytes actually read. This may be zero if EOF
--   was reached before any data was read (or if count is zero).
--   
--   hGetBufSome never raises an EOF exception, instead it returns a
--   value smaller than count.
--   
--   If the handle is a pipe or socket, and the writing end is closed,
--   hGetBufSome will behave as if EOF was reached.
--   
--   hGetBufSome ignores the prevailing TextEncoding and
--   NewlineMode on the Handle, and reads bytes directly.
hGetBufSome :: Handle -> Ptr a -> Int -> IO Int

-- | hGetBufNonBlocking hdl buf count reads data from the
--   handle hdl into the buffer buf until either EOF is
--   reached, or count 8-bit bytes have been read, or there is no
--   more data available to read immediately.
--   
--   hGetBufNonBlocking is identical to hGetBuf, except that
--   it will never block waiting for data to become available, instead it
--   returns only whatever data is available. To wait for data to arrive
--   before calling hGetBufNonBlocking, use hWaitForInput.
--   
--   If the handle is a pipe or socket, and the writing end is closed,
--   hGetBufNonBlocking will behave as if EOF was reached.
--   
--   hGetBufNonBlocking ignores the prevailing TextEncoding
--   and NewlineMode on the Handle, and reads bytes directly.
--   
--   NOTE: on Windows, this function does not work correctly; it behaves
--   identically to hGetBuf.
hGetBufNonBlocking :: Handle -> Ptr a -> Int -> IO Int

-- | Block the current thread until data is available to read on the given
--   file descriptor (GHC only).
--   
--   This will throw an IOError if the file descriptor was closed
--   while this thread was blocked. To safely close a file descriptor that
--   has been used with threadWaitRead, use closeFdWith.
threadWaitRead :: Fd -> IO ()

-- | Block the current thread until data can be written to the given file
--   descriptor (GHC only).
--   
--   This will throw an IOError if the file descriptor was closed
--   while this thread was blocked. To safely close a file descriptor that
--   has been used with threadWaitWrite, use closeFdWith.
threadWaitWrite :: Fd -> IO ()

-- | Returns an STM action that can be used to wait for data to read from a
--   file descriptor. The second returned value is an IO action that can be
--   used to deregister interest in the file descriptor.
threadWaitReadSTM :: Fd -> IO (STM (), IO ())

-- | Returns an STM action that can be used to wait until data can be
--   written to a file descriptor. The second returned value is an IO
--   action that can be used to deregister interest in the file descriptor.
threadWaitWriteSTM :: Fd -> IO (STM (), IO ())
withFile :: FilePath -> IOMode -> (Handle -> IO r) -> IO r
openBinaryFile :: FilePath -> IOMode -> IO Handle
withBinaryFile :: FilePath -> IOMode -> (Handle -> IO r) -> IO r

-- | For a handle hdl which attached to a physical file,
--   hFileSize hdl returns the size of that file in 8-bit
--   bytes.
hFileSize :: Handle -> IO Integer

-- | hSetFileSize hdl size truncates the physical
--   file with handle hdl to size bytes.
hSetFileSize :: Handle -> Integer -> IO ()

-- | For a readable handle hdl, hIsEOF hdl returns
--   True if no further input can be taken from hdl or for
--   a physical file, if the current I/O position is equal to the length of
--   the file. Otherwise, it returns False.
--   
--   NOTE: hIsEOF may block, because it has to attempt to read from
--   the stream to determine whether there is any more data to be read.
hIsEOF :: Handle -> IO Bool

-- | The computation isEOF is identical to hIsEOF, except
--   that it works only on stdin.
isEOF :: IO Bool

-- | Computation hSetBuffering hdl mode sets the mode of
--   buffering for handle hdl on subsequent reads and writes.
--   
--   If the buffer mode is changed from BlockBuffering or
--   LineBuffering to NoBuffering, then
--   
--   
--   
- if hdl is writable, the buffer is flushed as for
--   hFlush;
--   
- if hdl is not writable, the contents of the buffer is
--   discarded.
--   
--   
--   This operation may fail with:
--   
--   
--   
- isPermissionError if the handle has already been used for
--   reading or writing and the implementation does not allow the buffering
--   mode to be changed.
--   
hSetBuffering :: Handle -> BufferMode -> IO ()

-- | The action hSetEncoding hdl encoding changes
--   the text encoding for the handle hdl to encoding.
--   The default encoding when a Handle is created is
--   localeEncoding, namely the default encoding for the current
--   locale.
--   
--   To create a Handle with no encoding at all, use
--   openBinaryFile. To stop further encoding or decoding on an
--   existing Handle, use hSetBinaryMode.
--   
--   hSetEncoding may need to flush buffered data in order to change
--   the encoding.
hSetEncoding :: Handle -> TextEncoding -> IO ()

-- | Return the current TextEncoding for the specified
--   Handle, or Nothing if the Handle is in binary
--   mode.
--   
--   Note that the TextEncoding remembers nothing about the state of
--   the encoder/decoder in use on this Handle. For example, if the
--   encoding in use is UTF-16, then using hGetEncoding and
--   hSetEncoding to save and restore the encoding may result in an
--   extra byte-order-mark being written to the file.
hGetEncoding :: Handle -> IO (Maybe TextEncoding)

-- | Computation hGetPosn hdl returns the current I/O
--   position of hdl as a value of the abstract type
--   HandlePosn.
hGetPosn :: Handle -> IO HandlePosn

-- | If a call to hGetPosn hdl returns a position
--   p, then computation hSetPosn p sets the
--   position of hdl to the position it held at the time of the
--   call to hGetPosn.
--   
--   This operation may fail with:
--   
--   
--   
- isPermissionError if a system resource limit would be
--   exceeded.
--   
hSetPosn :: HandlePosn -> IO ()

-- | Computation hTell hdl returns the current position of
--   the handle hdl, as the number of bytes from the beginning of
--   the file. The value returned may be subsequently passed to
--   hSeek to reposition the handle to the current position.
--   
--   This operation may fail with:
--   
--   
--   
- isIllegalOperationError if the Handle is not seekable.
--   
hTell :: Handle -> IO Integer
hIsOpen :: Handle -> IO Bool
hIsClosed :: Handle -> IO Bool
hIsReadable :: Handle -> IO Bool
hIsWritable :: Handle -> IO Bool

-- | Computation hGetBuffering hdl returns the current
--   buffering mode for hdl.
hGetBuffering :: Handle -> IO BufferMode
hIsSeekable :: Handle -> IO Bool

-- | Set the echoing status of a handle connected to a terminal.
hSetEcho :: Handle -> Bool -> IO ()

-- | Get the echoing status of a handle connected to a terminal.
hGetEcho :: Handle -> IO Bool

-- | hShow is in the IO monad, and gives more comprehensive
--   output than the (pure) instance of Show for Handle.
hShow :: Handle -> IO String

-- | Write a character to the standard output device (same as
--   hPutChar stdout).
putChar :: Char -> IO ()

-- | Write a string to the standard output device (same as hPutStr
--   stdout).
putStr :: String -> IO ()

-- | Read a character from the standard input device (same as
--   hGetChar stdin).
getChar :: IO Char

-- | The getContents operation returns all user input as a single
--   string, which is read lazily as it is needed (same as
--   hGetContents stdin).
getContents :: IO String

-- | The getContents' operation returns all user input as a single
--   string, which is fully read before being returned (same as
--   hGetContents' stdin).
getContents' :: IO String

-- | The interact function takes a function of type
--   String->String as its argument. The entire input from the
--   standard input device is passed to this function as its argument, and
--   the resulting string is output on the standard output device.
interact :: (String -> String) -> IO ()

-- | The readFile function reads a file and returns the contents of
--   the file as a string. The file is read lazily, on demand, as with
--   getContents.
readFile :: FilePath -> IO String

-- | The computation appendFile file str function appends
--   the string str, to the file file.
--   
--   Note that writeFile and appendFile write a literal
--   string to a file. To write a value of any printable type, as with
--   print, use the show function to convert the value to a
--   string first.
--   
--   
--   main = appendFile "squares" (show [(x,x*x) | x <- [0,0.1..2]])
--   
appendFile :: FilePath -> String -> IO ()

-- | The readLn function combines getLine and readIO.
readLn :: Read a => IO a

-- | The readIO function is similar to read except that it
--   signals parse failure to the IO monad instead of terminating
--   the program.
readIO :: Read a => String -> IO a

-- | Computation hReady hdl indicates whether at least one
--   item is available for input from handle hdl.
--   
--   This operation may fail with:
--   
--   
--   
- isEOFError if the end of file has been reached.
--   
hReady :: Handle -> IO Bool

-- | Computation hPrint hdl t writes the string
--   representation of t given by the shows function to the
--   file or channel managed by hdl and appends a newline.
--   
--   This operation may fail with:
--   
--   
--   
- isFullError if the device is full; or
--   
- isPermissionError if another system resource limit would be
--   exceeded.
--   
hPrint :: Show a => Handle -> a -> IO ()

-- | The function creates a temporary file in ReadWrite mode. The created
--   file isn't deleted automatically, so you need to delete it manually.
--   
--   The file is created with permissions such that only the current user
--   can read/write it.
--   
--   With some exceptions (see below), the file will be created securely in
--   the sense that an attacker should not be able to cause openTempFile to
--   overwrite another file on the filesystem using your credentials, by
--   putting symbolic links (on Unix) in the place where the temporary file
--   is to be created. On Unix the O_CREAT and O_EXCL
--   flags are used to prevent this attack, but note that O_EXCL
--   is sometimes not supported on NFS filesystems, so if you rely on this
--   behaviour it is best to use local filesystems only.
openTempFile :: FilePath -> String -> IO (FilePath, Handle)

-- | Like openTempFile, but opens the file in binary mode. See
--   openBinaryFile for more comments.
openBinaryTempFile :: FilePath -> String -> IO (FilePath, Handle)

-- | Like openTempFile, but uses the default file permissions
openTempFileWithDefaultPermissions :: FilePath -> String -> IO (FilePath, Handle)

-- | Like openBinaryTempFile, but uses the default file permissions
openBinaryTempFileWithDefaultPermissions :: FilePath -> String -> IO (FilePath, Handle)

-- | The isSubsequenceOf function takes two lists and returns
--   True if all the elements of the first list occur, in order, in
--   the second. The elements do not have to occur consecutively.
--   
--   isSubsequenceOf x y is equivalent to elem x
--   (subsequences y).
--   
--   
--   >>> isSubsequenceOf "GHC" "The Glorious Haskell Compiler"
--   True
--   
--   >>> isSubsequenceOf ['a','d'..'z'] ['a'..'z']
--   True
--   
--   >>> isSubsequenceOf [1..10] [10,9..0]
--   False
--   
--   
--   For the result to be True, the first list must be finite; for
--   the result to be False, the second list must be finite:
--   
--   
--   >>> [0,2..10] `isSubsequenceOf` [0..]
--   True
--   
--   >>> [0..] `isSubsequenceOf` [0,2..10]
--   False
--   
--   >>> [0,2..] `isSubsequenceOf` [0..]
--   * Hangs forever*
--   
isSubsequenceOf :: Eq a => [a] -> [a] -> Bool

-- | This generalizes the list-based filter function.
filterM :: Applicative m => (a -> m Bool) -> [a] -> m [a]

-- | Left-to-right composition of Kleisli arrows.
--   
--   '(bs >=> cs) a' can be understood as the
--   do expression
--   
--   
--   do b <- bs a
--      cs b
--   
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c
infixr 1 >=>

-- | Right-to-left composition of Kleisli arrows.
--   (>=>), with the arguments flipped.
--   
--   Note how this operator resembles function composition
--   (.):
--   
--   
--   (.)   ::            (b ->   c) -> (a ->   b) -> a ->   c
--   (<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c
--   
(<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c
infixr 1 <=<

-- | The mapAndUnzipM function maps its first argument over a list,
--   returning the result as a pair of lists. This function is mainly used
--   with complicated data structures or a state monad.
mapAndUnzipM :: Applicative m => (a -> m (b, c)) -> [a] -> m ([b], [c])

-- | The zipWithM function generalizes zipWith to arbitrary
--   applicative functors.
zipWithM :: Applicative m => (a -> b -> m c) -> [a] -> [b] -> m [c]

-- | zipWithM_ is the extension of zipWithM which ignores the
--   final result.
zipWithM_ :: Applicative m => (a -> b -> m c) -> [a] -> [b] -> m ()

-- | The foldM function is analogous to foldl, except that
--   its result is encapsulated in a monad. Note that foldM works
--   from left-to-right over the list arguments. This could be an issue
--   where (>>) and the `folded function' are not
--   commutative.
--   
--   
--   foldM f a1 [x1, x2, ..., xm]
--   
--   ==
--   
--   do
--     a2 <- f a1 x1
--     a3 <- f a2 x2
--     ...
--     f am xm
--   
--   
--   If right-to-left evaluation is required, the input list should be
--   reversed.
--   
--   Note: foldM is the same as foldlM
foldM :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b

-- | Like foldM, but discards the result.
foldM_ :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m ()

-- | replicateM n act performs the action act
--   n times, and then returns the list of results:
--   
--   
Examples
--   
--   
--   >>> import Control.Monad.State
--   
--   >>> runState (replicateM 3 $ state $ \s -> (s, s + 1)) 1
--   ([1,2,3],4)
--   
replicateM :: Applicative m => Int -> m a -> m [a]

-- | Like replicateM, but discards the result.
--   
--   
Examples
--   
--   
--   >>> replicateM_ 3 (putStrLn "a")
--   a
--   a
--   a
--   
replicateM_ :: Applicative m => Int -> m a -> m ()

-- | The reverse of when.
unless :: Applicative f => Bool -> f () -> f ()

-- | Strict version of <$>.
(<$!>) :: Monad m => (a -> b) -> m a -> m b
infixl 4 <$!>

-- | Direct MonadPlus equivalent of filter.
--   
--   
Examples
--   
--   The filter function is just mfilter specialized to the
--   list monad:
--   
--   
--   filter = ( mfilter :: (a -> Bool) -> [a] -> [a] )
--   
--   
--   An example using mfilter with the Maybe monad:
--   
--   
--   >>> mfilter odd (Just 1)
--   Just 1
--   
--   >>> mfilter odd (Just 2)
--   Nothing
--   
mfilter :: MonadPlus m => (a -> Bool) -> m a -> m a

-- | The computation exitFailure is equivalent to exitWith
--   (ExitFailure exitfail), where
--   exitfail is implementation-dependent.
exitFailure :: IO a

-- | The computation exitSuccess is equivalent to exitWith
--   ExitSuccess, It terminates the program successfully.
exitSuccess :: IO a

-- | Write given error message to stderr and terminate with
--   exitFailure.
die :: String -> IO a

-- | Format a variable number of arguments with the C-style formatting
--   string.
--   
--   
--   >>> printf "%s, %d, %.4f" "hello" 123 pi
--   hello, 123, 3.1416
--   
--   
--   The return value is either String or (IO a)
--   (which should be (IO ()), but Haskell's type system
--   makes this hard).
--   
--   The format string consists of ordinary characters and conversion
--   specifications, which specify how to format one of the arguments
--   to printf in the output string. A format specification is
--   introduced by the % character; this character can be
--   self-escaped into the format string using %%. A format
--   specification ends with a format character that provides the
--   primary information about how to format the value. The rest of the
--   conversion specification is optional. In order, one may have flag
--   characters, a width specifier, a precision specifier, and
--   type-specific modifier characters.
--   
--   Unlike C printf(3), the formatting of this printf is
--   driven by the argument type; formatting is type specific. The types
--   formatted by printf "out of the box" are:
--   
--   
--   
- Integral types, including Char
--   
- String
--   
- RealFloat types
--   
--   
--   printf is also extensible to support other types: see below.
--   
--   A conversion specification begins with the character %,
--   followed by zero or more of the following flags:
--   
--   
--   -      left adjust (default is right adjust)
--   +      always use a sign (+ or -) for signed conversions
--   space  leading space for positive numbers in signed conversions
--   0      pad with zeros rather than spaces
--   #      use an \"alternate form\": see below
--   
--   
--   When both flags are given, - overrides 0 and
--   + overrides space. A negative width specifier in a *
--   conversion is treated as positive but implies the left adjust flag.
--   
--   The "alternate form" for unsigned radix conversions is as in C
--   printf(3):
--   
--   
--   %o           prefix with a leading 0 if needed
--   %x           prefix with a leading 0x if nonzero
--   %X           prefix with a leading 0X if nonzero
--   %b           prefix with a leading 0b if nonzero
--   %[eEfFgG]    ensure that the number contains a decimal point
--   
--   
--   Any flags are followed optionally by a field width:
--   
--   
--   num    field width
--   *      as num, but taken from argument list
--   
--   
--   The field width is a minimum, not a maximum: it will be expanded as
--   needed to avoid mutilating a value.
--   
--   Any field width is followed optionally by a precision:
--   
--   
--   .num   precision
--   .      same as .0
--   .*     as num, but taken from argument list
--   
--   
--   Negative precision is taken as 0. The meaning of the precision depends
--   on the conversion type.
--   
--   
--   Integral    minimum number of digits to show
--   RealFloat   number of digits after the decimal point
--   String      maximum number of characters
--   
--   
--   The precision for Integral types is accomplished by zero-padding. If
--   both precision and zero-pad are given for an Integral field, the
--   zero-pad is ignored.
--   
--   Any precision is followed optionally for Integral types by a width
--   modifier; the only use of this modifier being to set the implicit size
--   of the operand for conversion of a negative operand to unsigned:
--   
--   
--   hh     Int8
--   h      Int16
--   l      Int32
--   ll     Int64
--   L      Int64
--   
--   
--   The specification ends with a format character:
--   
--   
--   c      character               Integral
--   d      decimal                 Integral
--   o      octal                   Integral
--   x      hexadecimal             Integral
--   X      hexadecimal             Integral
--   b      binary                  Integral
--   u      unsigned decimal        Integral
--   f      floating point          RealFloat
--   F      floating point          RealFloat
--   g      general format float    RealFloat
--   G      general format float    RealFloat
--   e      exponent format float   RealFloat
--   E      exponent format float   RealFloat
--   s      string                  String
--   v      default format          any type
--   
--   
--   The "%v" specifier is provided for all built-in types, and should be
--   provided for user-defined type formatters as well. It picks a "best"
--   representation for the given type. For the built-in types the "%v"
--   specifier is converted as follows:
--   
--   
--   c      Char
--   u      other unsigned Integral
--   d      other signed Integral
--   g      RealFloat
--   s      String
--   
--   
--   Mismatch between the argument types and the format string, as well as
--   any other syntactic or semantic errors in the format string, will
--   cause an exception to be thrown at runtime.
--   
--   Note that the formatting for RealFloat types is currently a bit
--   different from that of C printf(3), conforming instead to
--   showEFloat, showFFloat and showGFloat (and their
--   alternate versions showFFloatAlt and showGFloatAlt).
--   This is hard to fix: the fixed versions would format in a
--   backward-incompatible way. In any case the Haskell behavior is
--   generally more sensible than the C behavior. A brief summary of some
--   key differences:
--   
--   
--   
- Haskell printf never uses the default "6-digit" precision
--   used by C printf.
--   
- Haskell printf treats the "precision" specifier as
--   indicating the number of digits after the decimal point.
--   
- Haskell printf prints the exponent of e-format numbers
--   without a gratuitous plus sign, and with the minimum possible number
--   of digits.
--   
- Haskell printf will place a zero after a decimal point when
--   possible.
--   
printf :: PrintfType r => String -> r

-- | Similar to printf, except that output is via the specified
--   Handle. The return type is restricted to (IO
--   a).
hPrintf :: HPrintfType r => Handle -> String -> r

-- | Substitute a 'v' format character with the given default format
--   character in the FieldFormat. A convenience for
--   user-implemented types, which should support "%v".
vFmt :: Char -> FieldFormat -> FieldFormat

-- | Formatter for Char values.
formatChar :: Char -> FieldFormatter

-- | Clip and pad a string to a minimum & maximum width, andor
--   leftright justify it. Works on multi-line strings too (but will
--   rewrite non-unix line endings).
formatString :: Bool -> Maybe Int -> Maybe Int -> String -> String

-- | Formatter for Int values.
formatInt :: (Integral a, Bounded a) => a -> FieldFormatter

-- | Formatter for Integer values.
formatInteger :: Integer -> FieldFormatter

-- | Raises an error with a printf-specific prefix on the message
--   string.
perror :: String -> a

-- | Calls perror to indicate an unknown format letter for a given
--   type.
errorBadFormat :: Char -> a

-- | Calls perror to indicate that the format string ended early.
errorShortFormat :: a

-- | Calls perror to indicate that there is a missing argument in
--   the argument list.
errorMissingArgument :: a

-- | Calls perror to indicate that there is a type error or similar
--   in the given argument.
errorBadArgument :: a

-- | Returns the absolute pathname of the current executable, or
--   argv[0] if the operating system does not provide a reliable
--   way query the current executable.
--   
--   Note that for scripts and interactive sessions, this is the path to
--   the interpreter (e.g. ghci.)
--   
--   Since base 4.11.0.0, getExecutablePath resolves symlinks on
--   Windows. If an executable is launched through a symlink,
--   getExecutablePath returns the absolute path of the original
--   executable.
--   
--   If the executable has been deleted, behaviour is ill-defined and
--   varies by operating system. See executablePath for a more
--   reliable way to query the current executable.
getExecutablePath :: IO FilePath

-- | Get an action to query the absolute pathname of the current
--   executable.
--   
--   If the operating system provides a reliable way to determine the
--   current executable, return the query action, otherwise return
--   Nothing. The action is defined on FreeBSD, Linux, MacOS,
--   NetBSD, and Windows.
--   
--   Even where the query action is defined, there may be situations where
--   no result is available, e.g. if the executable file was deleted while
--   the program is running. Therefore the result of the query action is a
--   Maybe FilePath.
--   
--   Note that for scripts and interactive sessions, the result is the path
--   to the interpreter (e.g. ghci.)
--   
--   Note also that while most operating systems return Nothing if
--   the executable file was deleted/unlinked, some (including NetBSD)
--   return the original path.
executablePath :: Maybe (IO (Maybe FilePath))

-- | Computation getProgName returns the name of the program as it
--   was invoked.
--   
--   However, this is hard-to-impossible to implement on some non-Unix
--   OSes, so instead, for maximum portability, we just return the leafname
--   of the program as invoked. Even then there are some differences
--   between platforms: on Windows, for example, a program invoked as foo
--   is probably really FOO.EXE, and that is what
--   getProgName will return.
getProgName :: IO String

-- | withArgs args act - while executing action
--   act, have getArgs return args.
withArgs :: [String] -> IO a -> IO a

-- | withProgName name act - while executing action
--   act, have getProgName return name.
withProgName :: String -> IO a -> IO a

-- | getEnvironment retrieves the entire environment as a list of
--   (key,value) pairs.
--   
--   If an environment entry does not contain an '=' character,
--   the key is the whole entry and the value is the
--   empty string.
getEnvironment :: IO [(String, String)]

-- | Like traceShow but returns the shown value instead of a third
--   value.
--   
--   
--   >>> traceShowId (1+2+3, "hello" ++ "world")
--   (6,"helloworld")
--   (6,"helloworld")
--   
traceShowId :: Show a => a -> a

-- | Trace a value with the given show function before returning it.
traceWith :: (a -> String) -> a -> a

-- | Build a new QSemN with a supplied initial quantity. The initial
--   quantity must be at least 0.
newQSemN :: Int -> IO QSemN

-- | Wait for the specified quantity to become available
waitQSemN :: QSemN -> Int -> IO ()

-- | Signal that a given quantity is now available from the QSemN.
signalQSemN :: QSemN -> Int -> IO ()

-- | Build a new QSem with a supplied initial quantity. The initial
--   quantity must be at least 0.
newQSem :: Int -> IO QSem

-- | Wait for a unit to become available
waitQSem :: QSem -> IO ()

-- | Signal that a unit of the QSem is available
signalQSem :: QSem -> IO ()

-- | Build and returns a new instance of Chan.
newChan :: IO (Chan a)

-- | Write a value to a Chan.
writeChan :: Chan a -> a -> IO ()

-- | Read the next value from the Chan. Blocks when the channel is
--   empty. Since the read end of a channel is an MVar, this
--   operation inherits fairness guarantees of MVars (e.g. threads
--   blocked in this operation are woken up in FIFO order).
--   
--   Throws BlockedIndefinitelyOnMVar when the channel is empty and
--   no other thread holds a reference to the channel.
readChan :: Chan a -> IO a

-- | Duplicate a Chan: the duplicate channel begins empty, but data
--   written to either channel from then on will be available from both.
--   Hence this creates a kind of broadcast channel, where data written by
--   anyone is seen by everyone else.
--   
--   (Note that a duplicated channel is not equal to its original. So:
--   fmap (c /=) $ dupChan c returns True for all
--   c.)
dupChan :: Chan a -> IO (Chan a)

-- | Return a lazy list representing the contents of the supplied
--   Chan, much like hGetContents.
getChanContents :: Chan a -> IO [a]

-- | Write an entire list of items to a Chan.
writeList2Chan :: Chan a -> [a] -> IO ()

-- | True if bound threads are supported. If
--   rtsSupportsBoundThreads is False,
--   isCurrentThreadBound will always return False and both
--   forkOS and runInBoundThread will fail.
rtsSupportsBoundThreads :: Bool

-- | Like forkIOWithUnmask, but the child thread is a bound thread,
--   as with forkOS.
forkOSWithUnmask :: ((forall a. () => IO a -> IO a) -> IO ()) -> IO ThreadId

-- | Returns True if the calling thread is bound, that is, if
--   it is safe to use foreign libraries that rely on thread-local state
--   from the calling thread.
isCurrentThreadBound :: IO Bool

-- | Run the IO computation passed as the first argument. If the
--   calling thread is not bound, a bound thread is created
--   temporarily. runInBoundThread doesn't finish until the
--   IO computation finishes.
--   
--   You can wrap a series of foreign function calls that rely on
--   thread-local state with runInBoundThread so that you can use
--   them without knowing whether the current thread is bound.
runInBoundThread :: IO a -> IO a

-- | Run the IO computation passed as the first argument. If the
--   calling thread is bound, an unbound thread is created
--   temporarily using forkIO. runInBoundThread doesn't
--   finish until the IO computation finishes.
--   
--   Use this function only in the rare case that you have actually
--   observed a performance loss due to the use of bound threads. A program
--   that doesn't need its main thread to be bound and makes heavy
--   use of concurrency (e.g. a web server), might want to wrap its
--   main action in runInUnboundThread.
--   
--   Note that exceptions which are thrown to the current thread are thrown
--   in turn to the thread that is executing the given computation. This
--   ensures there's always a way of killing the forked thread.
runInUnboundThread :: IO a -> IO a

-- | The diff command.
diff :: CliOpts -> Journal -> IO ()

-- | O(n) Convert a String into a Text. Performs
--   replacement on invalid scalar values, so unpack .
--   pack is not id:
--   
--   
--   >>> Data.Text.unpack (pack "\55555")
--   "\65533"
--   
pack :: String -> Text

-- | O(n) Convert a Text into a String.
unpack :: Text -> String

-- | Take elements from the end of a list.
takeEnd :: Int -> [a] -> [a]
spanEnd :: DateSpan -> Maybe Day

-- | Remove leading and trailing whitespace.
strip :: String -> String

-- | Expand @ directives in a list of arguments, usually obtained
--   from getArgs. As an example, given the file test.txt
--   with the lines hello and world:
--   
--   
--   expandArgsAt ["@test.txt","!"] == ["hello","world","!"]
--   
--   
--   Any @ directives in the files will be recursively expanded
--   (raising an error if there is infinite recursion).
--   
--   To supress @ expansion, pass any @ arguments after
--   --.
expandArgsAt :: [String] -> IO [String]

-- | Given a sequence of arguments, join them together in a manner that
--   could be used on the command line, giving preference to the Windows
--   cmd shell quoting conventions.
--   
--   For an alternative version, intended for actual running the result in
--   a shell, see "System.Process.showCommandForUser"
joinArgs :: [String] -> String

-- | Given a string, split into the available arguments. The inverse of
--   joinArgs.
splitArgs :: String -> [String]

-- | Parse a boolean, accepts as True: true yes on enabled 1.
parseBool :: String -> Maybe Bool

-- | Convert a group into a list.
fromGroup :: Group a -> [a]

-- | Convert a list into a group, placing all fields in
--   groupUnnamed.
toGroup :: [a] -> Group a

-- | Extract the modes from a Mode
modeModes :: Mode a -> [Mode a]

-- | Extract the flags from a Mode
modeFlags :: Mode a -> [Flag a]

-- | Extract the value from inside a FlagOpt or FlagOptRare,
--   or raises an error.
fromFlagOpt :: FlagInfo -> String

-- | Check that a mode is well formed.
checkMode :: Mode a -> Maybe String

-- | Restricted version of remap where the values are isomorphic.
remap2 :: Remap m => (a -> b) -> (b -> a) -> m a -> m b

-- | Version of remap for the Update type alias.
remapUpdate :: (a -> b) -> (b -> (a, a -> b)) -> Update a -> Update b

-- | Create an empty mode specifying only modeValue. All other
--   fields will usually be populated using record updates.
modeEmpty :: a -> Mode a

-- | Create a mode with a name, an initial value, some help text, a way of
--   processing arguments and a list of flags.
mode :: Name -> a -> Help -> Arg a -> [Flag a] -> Mode a

-- | Create a list of modes, with a program name, an initial value, some
--   help text and the child modes.
modes :: String -> a -> Help -> [Mode a] -> Mode a

-- | Create a flag taking no argument value, with a list of flag names, an
--   update function and some help text.
flagNone :: [Name] -> (a -> a) -> Help -> Flag a

-- | Create a flag taking an optional argument value, with an optional
--   value, a list of flag names, an update function, the type of the
--   argument and some help text.
flagOpt :: String -> [Name] -> Update a -> FlagHelp -> Help -> Flag a

-- | Create a flag taking a required argument value, with a list of flag
--   names, an update function, the type of the argument and some help
--   text.
flagReq :: [Name] -> Update a -> FlagHelp -> Help -> Flag a

-- | Create an argument flag, with an update function and the type of the
--   argument.
flagArg :: Update a -> FlagHelp -> Arg a

-- | Create a boolean flag, with a list of flag names, an update function
--   and some help text.
flagBool :: [Name] -> (Bool -> a -> a) -> Help -> Flag a

-- | Given a current state, return the set of commands you could type now,
--   in preference order.
complete :: Mode a -> [String] -> (Int, Int) -> [Complete]

-- | Generate a help message from a mode. The first argument is a prefix,
--   which is prepended when not using HelpFormatBash or
--   HelpFormatZsh.
helpText :: [String] -> HelpFormat -> Mode a -> [Text]

-- | Process the flags obtained by getArgs and
--   expandArgsAt with a mode. Displays an error and exits
--   with failure if the command line fails to parse, or returns the
--   associated value. Implemented in terms of process. This
--   function makes use of the following environment variables:
--   
--   
--   
- $CMDARGS_COMPLETE - causes the program to produce
--   completions using complete, then exit. Completions are based on
--   the result of getArgs, the index of the current argument is
--   taken from $CMDARGS_COMPLETE (set it to - to
--   complete the last argument), and the index within that argument is
--   taken from $CMDARGS_COMPLETE_POS (if set).
--   
- $CMDARGS_HELPER/$CMDARGS_HELPER_PROG -
--   uses the helper mechanism for entering command line programs as
--   described in System.Console.CmdArgs.Helper.
--   
processArgs :: Mode a -> IO a

-- | Process a list of flags (usually obtained from getArgs
--   and expandArgsAt) with a mode. Throws an error if the
--   command line fails to parse, or returns the associated value.
--   Implemeneted in terms of process. This function does not take
--   account of any environment variables that may be set (see
--   processArgs).
--   
--   If you are in IO you will probably get a better user experience
--   by calling processValueIO.
processValue :: Mode a -> [String] -> a

-- | Like processValue but on failure prints to stderr and exits the
--   program.
processValueIO :: Mode a -> [String] -> IO a

-- | Create a help flag triggered by -?/--help.
flagHelpSimple :: (a -> a) -> Flag a

-- | Create a help flag triggered by -?/--help. The user
--   may optionally modify help by specifying the format, such as:
--   
--   
--   --help=all          - help for all modes
--   --help=html         - help in HTML format
--   --help=100          - wrap the text at 100 characters
--   --help=100,one      - full text wrapped at 100 characters
--   
flagHelpFormat :: (HelpFormat -> TextFormat -> a -> a) -> Flag a

-- | Create a version flag triggered by -V/--version.
flagVersion :: (a -> a) -> Flag a

-- | Create a version flag triggered by --numeric-version.
flagNumericVersion :: (a -> a) -> Flag a

-- | Create verbosity flags triggered by -v/--verbose and
--   -q/--quiet
flagsVerbosity :: (Verbosity -> a -> a) -> [Flag a]

-- | Wrap a Text with the surrounding Text.
wrap :: Text -> Text -> Text -> Text

-- | The balance command, prints a balance report.
balance :: CliOpts -> Journal -> IO ()

-- | The character that is used to separate the entries in the $PATH
--   environment variable.
--   
--   
--   Windows: searchPathSeparator == ';'
--   Posix:   searchPathSeparator == ':'
--   
searchPathSeparator :: Char

-- | removeDirectory dir removes an existing directory
--   dir. The implementation may specify additional constraints
--   which must be satisfied before a directory can be removed (e.g. the
--   directory has to be empty, or may not be in use by other processes).
--   It is not legal for an implementation to partially remove a directory
--   unless the entire directory is removed. A conformant implementation
--   need not support directory removal in all situations (e.g. removal of
--   the root directory).
--   
--   The operation may fail with:
--   
--   
--   
- HardwareFault A physical I/O error has occurred.
--   [EIO]
--   
- InvalidArgument The operand is not a valid directory
--   name. [ENAMETOOLONG, ELOOP]
--   
- isDoesNotExistError The directory does not exist.
--   [ENOENT, ENOTDIR]
--   
- isPermissionError The process has insufficient privileges
--   to perform the operation. [EROFS, EACCES, EPERM]
--   
- UnsatisfiedConstraints Implementation-dependent
--   constraints are not satisfied. [EBUSY, ENOTEMPTY,
--   EEXIST]
--   
- UnsupportedOperation The implementation does not support
--   removal in this situation. [EINVAL]
--   
- InappropriateType The operand refers to an existing
--   non-directory object. [ENOTDIR]
--   
removeDirectory :: FilePath -> IO ()

-- | removeFile file removes the directory entry for an
--   existing file file, where file is not itself a
--   directory. The implementation may specify additional constraints which
--   must be satisfied before a file can be removed (e.g. the file may not
--   be in use by other processes).
--   
--   The operation may fail with:
--   
--   
--   
- HardwareFault A physical I/O error has occurred.
--   [EIO]
--   
- InvalidArgument The operand is not a valid file name.
--   [ENAMETOOLONG, ELOOP]
--   
- isDoesNotExistError The file does not exist. [ENOENT,
--   ENOTDIR]
--   
- isPermissionError The process has insufficient privileges
--   to perform the operation. [EROFS, EACCES, EPERM]
--   
- UnsatisfiedConstraints Implementation-dependent
--   constraints are not satisfied. [EBUSY]
--   
- InappropriateType The operand refers to an existing
--   directory. [EPERM, EINVAL]
--   
removeFile :: FilePath -> IO ()

-- | Normalise a file
--   
--   
--   
- // outside of the drive can be made blank
--   
- / -> pathSeparator
--   
- ./ -> ""
--   
--   
--   Does not remove "..", because of symlinks.
--   
--   
--   Posix:   normalise "/file/\\test////" == "/file/\\test/"
--   Posix:   normalise "/file/./test" == "/file/test"
--   Posix:   normalise "/test/file/../bob/fred/" == "/test/file/../bob/fred/"
--   Posix:   normalise "../bob/fred/" == "../bob/fred/"
--   Posix:   normalise "/a/../c" == "/a/../c"
--   Posix:   normalise "./bob/fred/" == "bob/fred/"
--   Windows: normalise "c:\\file/bob\\" == "C:\\file\\bob\\"
--   Windows: normalise "c:\\" == "C:\\"
--   Windows: normalise "c:\\\\\\\\" == "C:\\"
--   Windows: normalise "C:.\\" == "C:"
--   Windows: normalise "\\\\server\\test" == "\\\\server\\test"
--   Windows: normalise "//server/test" == "\\\\server\\test"
--   Windows: normalise "c:/file" == "C:\\file"
--   Windows: normalise "/file" == "\\file"
--   Windows: normalise "\\" == "\\"
--   Windows: normalise "/./" == "\\"
--            normalise "." == "."
--   Posix:   normalise "./" == "./"
--   Posix:   normalise "./." == "./"
--   Posix:   normalise "/./" == "/"
--   Posix:   normalise "/" == "/"
--   Posix:   normalise "bob/fred/." == "bob/fred/"
--   Posix:   normalise "//home" == "/home"
--   
normalise :: FilePath -> FilePath
emptyPermissions :: Permissions
setOwnerReadable :: Bool -> Permissions -> Permissions
setOwnerWritable :: Bool -> Permissions -> Permissions
setOwnerExecutable :: Bool -> Permissions -> Permissions
setOwnerSearchable :: Bool -> Permissions -> Permissions

-- | Get the permissions of a file or directory.
--   
--   On Windows, the writable permission corresponds to the
--   "read-only" attribute. The executable permission is set if the
--   file extension is of an executable file type. The readable
--   permission is always set.
--   
--   On POSIX systems, this returns the result of access.
--   
--   The operation may fail with:
--   
--   
--   
- isPermissionError if the user is not permitted to access
--   the permissions, or
--   
- isDoesNotExistError if the file or directory does not
--   exist.
--   
getPermissions :: FilePath -> IO Permissions

-- | Set the permissions of a file or directory.
--   
--   On Windows, this is only capable of changing the writable
--   permission, which corresponds to the "read-only" attribute. Changing
--   the other permissions has no effect.
--   
--   On POSIX systems, this sets the owner permissions.
--   
--   The operation may fail with:
--   
--   
--   
- isPermissionError if the user is not permitted to set the
--   permissions, or
--   
- isDoesNotExistError if the file or directory does not
--   exist.
--   
setPermissions :: FilePath -> Permissions -> IO ()

-- | Copy the permissions of one file to another. This reproduces the
--   permissions more accurately than using getPermissions followed
--   by setPermissions.
--   
--   On Windows, this copies only the read-only attribute.
--   
--   On POSIX systems, this is equivalent to stat followed by
--   chmod.
copyPermissions :: FilePath -> FilePath -> IO ()

-- | createDirectory dir creates a new directory
--   dir which is initially empty, or as near to empty as the
--   operating system allows.
--   
--   The operation may fail with:
--   
--   
--   
- isPermissionError The process has insufficient privileges
--   to perform the operation. [EROFS, EACCES]
--   
- isAlreadyExistsError The operand refers to a directory that
--   already exists.  [EEXIST]
--   
- HardwareFault A physical I/O error has occurred.
--   [EIO]
--   
- InvalidArgument The operand is not a valid directory
--   name. [ENAMETOOLONG, ELOOP]
--   
- isDoesNotExistError There is no path to the directory.
--   [ENOENT, ENOTDIR]
--   
- isFullError Insufficient resources (virtual memory, process
--   file descriptors, physical disk space, etc.) are available to perform
--   the operation. [EDQUOT, ENOSPC, ENOMEM, EMLINK]
--   
- InappropriateType The path refers to an existing
--   non-directory object. [EEXIST]
--   
createDirectory :: FilePath -> IO ()

-- | createDirectoryIfMissing parents dir creates a new
--   directory dir if it doesn't exist. If the first argument is
--   True the function will also create all parent directories if
--   they are missing.
createDirectoryIfMissing :: Bool -> FilePath -> IO ()

-- | removeDirectoryRecursive dir removes an existing
--   directory dir together with its contents and subdirectories.
--   Within this directory, symbolic links are removed without affecting
--   their targets.
--   
--   On Windows, the operation fails if dir is a directory symbolic
--   link.
--   
--   This operation is reported to be flaky on Windows so retry logic may
--   be advisable. See:
--   https://github.com/haskell/directory/pull/108
removeDirectoryRecursive :: FilePath -> IO ()

-- | Removes a file or directory at path together with its contents
--   and subdirectories. Symbolic links are removed without affecting their
--   targets. If the path does not exist, nothing happens.
--   
--   Unlike other removal functions, this function will also attempt to
--   delete files marked as read-only or otherwise made unremovable due to
--   permissions. As a result, if the removal is incomplete, the
--   permissions or attributes on the remaining files may be altered. If
--   there are hard links in the directory, then permissions on all related
--   hard links may be altered.
--   
--   If an entry within the directory vanishes while
--   removePathForcibly is running, it is silently ignored.
--   
--   If an exception occurs while removing an entry,
--   removePathForcibly will still try to remove as many entries
--   as it can before failing with an exception. The first exception that
--   it encountered is re-thrown.
removePathForcibly :: FilePath -> IO ()

-- | renameDirectory old new changes the name of an
--   existing directory from old to new. If the new
--   directory already exists, it is atomically replaced by the old
--   directory. If the new directory is neither the old
--   directory nor an alias of the old directory, it is removed as
--   if by removeDirectory. A conformant implementation need not
--   support renaming directories in all situations (e.g. renaming to an
--   existing directory, or across different physical devices), but the
--   constraints must be documented.
--   
--   On Win32 platforms, renameDirectory fails if the new
--   directory already exists.
--   
--   The operation may fail with:
--   
--   
--   
- HardwareFault A physical I/O error has occurred.
--   [EIO]
--   
- InvalidArgument Either operand is not a valid directory
--   name. [ENAMETOOLONG, ELOOP]
--   
- isDoesNotExistError The original directory does not exist,
--   or there is no path to the target. [ENOENT, ENOTDIR]
--   
- isPermissionError The process has insufficient privileges
--   to perform the operation. [EROFS, EACCES, EPERM]
--   
- isFullError Insufficient resources are available to perform
--   the operation. [EDQUOT, ENOSPC, ENOMEM, EMLINK]
--   
- UnsatisfiedConstraints Implementation-dependent
--   constraints are not satisfied. [EBUSY, ENOTEMPTY,
--   EEXIST]
--   
- UnsupportedOperation The implementation does not support
--   renaming in this situation. [EINVAL, EXDEV]
--   
- InappropriateType Either path refers to an existing
--   non-directory object. [ENOTDIR, EISDIR]
--   
renameDirectory :: FilePath -> FilePath -> IO ()

-- | renameFile old new changes the name of an existing
--   file system object from old to new. If the new
--   object already exists, it is replaced by the old object.
--   Neither path may refer to an existing directory.
--   
--   A conformant implementation need not support renaming files in all
--   situations (e.g. renaming across different physical devices), but the
--   constraints must be documented. On Windows, this does not support
--   renaming across different physical devices; if you are looking to do
--   so, consider using copyFileWithMetadata and removeFile.
--   
--   On Windows, this calls MoveFileEx with
--   MOVEFILE_REPLACE_EXISTING set, which is not guaranteed to be
--   atomic (https://github.com/haskell/directory/issues/109).
--   
--   On other platforms, this operation is atomic.
--   
--   The operation may fail with:
--   
--   
--   
- HardwareFault A physical I/O error has occurred.
--   [EIO]
--   
- InvalidArgument Either operand is not a valid file name.
--   [ENAMETOOLONG, ELOOP]
--   
- isDoesNotExistError The original file does not exist, or
--   there is no path to the target. [ENOENT, ENOTDIR]
--   
- isPermissionError The process has insufficient privileges
--   to perform the operation. [EROFS, EACCES, EPERM]
--   
- isFullError Insufficient resources are available to perform
--   the operation. [EDQUOT, ENOSPC, ENOMEM, EMLINK]
--   
- UnsatisfiedConstraints Implementation-dependent
--   constraints are not satisfied. [EBUSY]
--   
- UnsupportedOperation The implementation does not support
--   renaming in this situation. [EXDEV]
--   
- InappropriateType Either path refers to an existing
--   directory. [ENOTDIR, EISDIR, EINVAL, EEXIST, ENOTEMPTY]
--   
renameFile :: FilePath -> FilePath -> IO ()

-- | Rename a file or directory. If the destination path already exists, it
--   is replaced atomically. The destination path must not point to an
--   existing directory. A conformant implementation need not support
--   renaming files in all situations (e.g. renaming across different
--   physical devices), but the constraints must be documented.
--   
--   The operation may fail with:
--   
--   
--   
- HardwareFault A physical I/O error has occurred.
--   [EIO]
--   
- InvalidArgument Either operand is not a valid file name.
--   [ENAMETOOLONG, ELOOP]
--   
- isDoesNotExistError The original file does not exist, or
--   there is no path to the target. [ENOENT, ENOTDIR]
--   
- isPermissionError The process has insufficient privileges
--   to perform the operation. [EROFS, EACCES, EPERM]
--   
- isFullError Insufficient resources are available to perform
--   the operation. [EDQUOT, ENOSPC, ENOMEM, EMLINK]
--   
- UnsatisfiedConstraints Implementation-dependent
--   constraints are not satisfied. [EBUSY]
--   
- UnsupportedOperation The implementation does not support
--   renaming in this situation. [EXDEV]
--   
- InappropriateType Either the destination path refers to
--   an existing directory, or one of the parent segments in the
--   destination path is not a directory. [ENOTDIR, EISDIR, EINVAL,
--   EEXIST, ENOTEMPTY]
--   
renamePath :: FilePath -> FilePath -> IO ()

-- | Copy a file with its permissions. If the destination file already
--   exists, it is replaced atomically. Neither path may refer to an
--   existing directory. No exceptions are thrown if the permissions could
--   not be copied.
copyFile :: FilePath -> FilePath -> IO ()

-- | Copy a file with its associated metadata. If the destination file
--   already exists, it is overwritten. There is no guarantee of atomicity
--   in the replacement of the destination file. Neither path may refer to
--   an existing directory. If the source and/or destination are symbolic
--   links, the copy is performed on the targets of the links.
--   
--   On Windows, it behaves like the Win32 function CopyFile, which
--   copies various kinds of metadata including file attributes and
--   security resource properties.
--   
--   On Unix-like systems, permissions, access time, and modification time
--   are preserved. If possible, the owner and group are also preserved.
--   Note that the very act of copying can change the access time of the
--   source file, hence the access times of the two files may differ after
--   the operation completes.
copyFileWithMetadata :: FilePath -> FilePath -> IO ()

-- | Make a path absolute, normalize the path, and remove as many
--   indirections from it as possible. Any trailing path separators are
--   discarded via dropTrailingPathSeparator. Additionally, on
--   Windows the letter case of the path is canonicalized.
--   
--   Note: This function is a very big hammer. If you only need an
--   absolute path, makeAbsolute is sufficient for removing
--   dependence on the current working directory.
--   
--   Indirections include the two special directories . and
--   .., as well as any symbolic links (and junction points on
--   Windows). The input path need not point to an existing file or
--   directory. Canonicalization is performed on the longest prefix of the
--   path that points to an existing file or directory. The remaining
--   portion of the path that does not point to an existing file or
--   directory will still be normalized, but case canonicalization and
--   indirection removal are skipped as they are impossible to do on a
--   nonexistent path.
--   
--   Most programs should not worry about the canonicity of a path. In
--   particular, despite the name, the function does not truly guarantee
--   canonicity of the returned path due to the presence of hard links,
--   mount points, etc.
--   
--   If the path points to an existing file or directory, then the output
--   path shall also point to the same file or directory, subject to the
--   condition that the relevant parts of the file system do not change
--   while the function is still running. In other words, the function is
--   definitively not atomic. The results can be utterly wrong if the
--   portions of the path change while this function is running.
--   
--   Since some indirections (symbolic links on all systems, .. on
--   non-Windows systems, and junction points on Windows) are dependent on
--   the state of the existing filesystem, the function can only make a
--   conservative attempt by removing such indirections from the longest
--   prefix of the path that still points to an existing file or directory.
--   
--   Note that on Windows parent directories .. are always fully
--   expanded before the symbolic links, as consistent with the rest of the
--   Windows API (such as GetFullPathName). In contrast, on POSIX
--   systems parent directories .. are expanded alongside symbolic
--   links from left to right. To put this more concretely: if L
--   is a symbolic link for R/P, then on Windows L\..
--   refers to ., whereas on other operating systems L/..
--   refers to R.
--   
--   Similar to normalise, passing an empty path is equivalent to
--   passing the current directory.
--   
--   canonicalizePath can resolve at least 64 indirections in a
--   single path, more than what is supported by most operating systems.
--   Therefore, it may return the fully resolved path even though the
--   operating system itself would have long given up.
--   
--   On Windows XP or earlier systems, junction expansion is not performed
--   due to their lack of GetFinalPathNameByHandle.
--   
--   Changes since 1.2.3.0: The function has been altered to be more
--   robust and has the same exception behavior as makeAbsolute.
--   
--   Changes since 1.3.0.0: The function no longer preserves the
--   trailing path separator. File symbolic links that appear in the middle
--   of a path are properly dereferenced. Case canonicalization and
--   symbolic link expansion are now performed on Windows.
canonicalizePath :: FilePath -> IO FilePath

-- | Convert a path into an absolute path. If the given path is relative,
--   the current directory is prepended and then the combined result is
--   normalized. If the path is already absolute, the path is simply
--   normalized. The function preserves the presence or absence of the
--   trailing path separator unless the path refers to the root directory
--   /.
--   
--   If the path is already absolute, the operation never fails. Otherwise,
--   the operation may fail with the same exceptions as
--   getCurrentDirectory.
makeAbsolute :: FilePath -> IO FilePath

-- | Construct a path relative to the current directory, similar to
--   makeRelative.
--   
--   The operation may fail with the same exceptions as
--   getCurrentDirectory.
makeRelativeToCurrentDirectory :: FilePath -> IO FilePath

-- | Given the name or path of an executable file, findExecutable
--   searches for such a file in a list of system-defined locations, which
--   generally includes PATH and possibly more. The full path to
--   the executable is returned if found. For example, (findExecutable
--   "ghc") would normally give you the path to GHC.
--   
--   The path returned by findExecutable name corresponds
--   to the program that would be executed by createProcess
--   when passed the same string (as a RawCommand, not a
--   ShellCommand), provided that name is not a relative
--   path with more than one segment.
--   
--   On Windows, findExecutable calls the Win32 function
--   SearchPath, which may search other places before
--   checking the directories in the PATH environment variable.
--   Where it actually searches depends on registry settings, but notably
--   includes the directory containing the current executable.
--   
--   On non-Windows platforms, the behavior is equivalent to
--   findFileWith using the search directories from the
--   PATH environment variable and testing each file for
--   executable permissions. Details can be found in the documentation of
--   findFileWith.
findExecutable :: String -> IO (Maybe FilePath)

-- | Search for executable files in a list of system-defined locations,
--   which generally includes PATH and possibly more.
--   
--   On Windows, this only returns the first occurrence, if any. Its
--   behavior is therefore equivalent to findExecutable.
--   
--   On non-Windows platforms, the behavior is equivalent to
--   findExecutablesInDirectories using the search directories from
--   the PATH environment variable. Details can be found in the
--   documentation of findExecutablesInDirectories.
findExecutables :: String -> IO [FilePath]

-- | Given a name or path, findExecutable appends the
--   exeExtension to the query and searches for executable files in
--   the list of given search directories and returns all occurrences.
--   
--   The behavior is equivalent to findFileWith using the given
--   search directories and testing each file for executable permissions.
--   Details can be found in the documentation of findFileWith.
--   
--   Unlike other similarly named functions,
--   findExecutablesInDirectories does not use SearchPath
--   from the Win32 API. The behavior of this function on Windows is
--   therefore equivalent to those on non-Windows platforms.
findExecutablesInDirectories :: [FilePath] -> String -> IO [FilePath]

-- | Search through the given list of directories for the given file.
--   
--   The behavior is equivalent to findFileWith, returning only the
--   first occurrence. Details can be found in the documentation of
--   findFileWith.
findFile :: [FilePath] -> String -> IO (Maybe FilePath)

-- | Search through the given list of directories for the given file and
--   returns all paths where the given file exists.
--   
--   The behavior is equivalent to findFilesWith. Details can be
--   found in the documentation of findFilesWith.
findFiles :: [FilePath] -> String -> IO [FilePath]

-- | Search through a given list of directories for a file that has the
--   given name and satisfies the given predicate and return the path of
--   the first occurrence. The directories are checked in a left-to-right
--   order.
--   
--   This is essentially a more performant version of findFilesWith
--   that always returns the first result, if any. Details can be found in
--   the documentation of findFilesWith.
findFileWith :: (FilePath -> IO Bool) -> [FilePath] -> String -> IO (Maybe FilePath)

-- | findFilesWith predicate dirs name searches through the list
--   of directories (dirs) for files that have the given
--   name and satisfy the given predicate and returns the
--   paths of those files. The directories are checked in a left-to-right
--   order and the paths are returned in the same order.
--   
--   If the name is a relative path, then for every search
--   directory dir, the function checks whether dir
--   </> name exists and satisfies the predicate. If
--   so, dir </> name is returned as one of the
--   results. In other words, the returned paths can be either relative or
--   absolute depending on the search directories were used. If there are
--   no search directories, no results are ever returned.
--   
--   If the name is an absolute path, then the function will
--   return a single result if the file exists and satisfies the predicate
--   and no results otherwise. This is irrespective of what search
--   directories were given.
findFilesWith :: (FilePath -> IO Bool) -> [FilePath] -> String -> IO [FilePath]

-- | Filename extension for executable files (including the dot if any)
--   (usually "" on POSIX systems and ".exe" on Windows
--   or OS/2).
exeExtension :: String

-- | listDirectory dir returns a list of all entries
--   in dir without the special entries (. and
--   ..).
--   
--   The operation may fail with:
--   
--   
--   
- HardwareFault A physical I/O error has occurred.
--   [EIO]
--   
- InvalidArgument The operand is not a valid directory
--   name. [ENAMETOOLONG, ELOOP]
--   
- isDoesNotExistError The directory does not exist.
--   [ENOENT, ENOTDIR]
--   
- isPermissionError The process has insufficient privileges
--   to perform the operation. [EACCES]
--   
- isFullError Insufficient resources are available to perform
--   the operation. [EMFILE, ENFILE]
--   
- InappropriateType The path refers to an existing
--   non-directory object. [ENOTDIR]
--   
listDirectory :: FilePath -> IO [FilePath]

-- | Obtain the current working directory as an absolute path.
--   
--   In a multithreaded program, the current working directory is a global
--   state shared among all threads of the process. Therefore, when
--   performing filesystem operations from multiple threads, it is highly
--   recommended to use absolute rather than relative paths (see:
--   makeAbsolute).
--   
--   Note that getCurrentDirectory is not guaranteed to return the
--   same path received by setCurrentDirectory. On POSIX systems,
--   the path returned will always be fully dereferenced (not contain any
--   symbolic links). For more information, refer to the documentation of
--   getcwd.
--   
--   The operation may fail with:
--   
--   
--   
- HardwareFault A physical I/O error has occurred.
--   [EIO]
--   
- isDoesNotExistError There is no path referring to the
--   working directory. [EPERM, ENOENT, ESTALE...]
--   
- isPermissionError The process has insufficient privileges
--   to perform the operation. [EACCES]
--   
- isFullError Insufficient resources are available to perform
--   the operation.
--   
- UnsupportedOperation The operating system has no notion
--   of current working directory.
--   
getCurrentDirectory :: IO FilePath

-- | Change the working directory to the given path.
--   
--   In a multithreaded program, the current working directory is a global
--   state shared among all threads of the process. Therefore, when
--   performing filesystem operations from multiple threads, it is highly
--   recommended to use absolute rather than relative paths (see:
--   makeAbsolute).
--   
--   The operation may fail with:
--   
--   
--   
- HardwareFault A physical I/O error has occurred.
--   [EIO]
--   
- InvalidArgument The operand is not a valid directory
--   name. [ENAMETOOLONG, ELOOP]
--   
- isDoesNotExistError The directory does not exist.
--   [ENOENT, ENOTDIR]
--   
- isPermissionError The process has insufficient privileges
--   to perform the operation. [EACCES]
--   
- UnsupportedOperation The operating system has no notion
--   of current working directory, or the working directory cannot be
--   dynamically changed.
--   
- InappropriateType The path refers to an existing
--   non-directory object. [ENOTDIR]
--   
setCurrentDirectory :: FilePath -> IO ()

-- | Run an IO action with the given working directory and restore
--   the original working directory afterwards, even if the given action
--   fails due to an exception.
--   
--   The operation may fail with the same exceptions as
--   getCurrentDirectory and setCurrentDirectory.
withCurrentDirectory :: FilePath -> IO a -> IO a

-- | Obtain the size of a file in bytes.
getFileSize :: FilePath -> IO Integer

-- | Test whether the given path points to an existing filesystem object.
--   If the user lacks necessary permissions to search the parent
--   directories, this function may return false even if the file does
--   actually exist.
doesPathExist :: FilePath -> IO Bool

-- | The operation doesDirectoryExist returns True if the
--   argument file exists and is either a directory or a symbolic link to a
--   directory, and False otherwise.
doesDirectoryExist :: FilePath -> IO Bool

-- | The operation doesFileExist returns True if the argument
--   file exists and is not a directory, and False otherwise.
doesFileExist :: FilePath -> IO Bool

-- | Create a file symbolic link. The target path can be either
--   absolute or relative and need not refer to an existing file. The order
--   of arguments follows the POSIX convention.
--   
--   To remove an existing file symbolic link, use removeFile.
--   
--   Although the distinction between file symbolic links and
--   directory symbolic links does not exist on POSIX systems, on
--   Windows this is an intrinsic property of every symbolic link and
--   cannot be changed without recreating the link. A file symbolic link
--   that actually points to a directory will fail to dereference and vice
--   versa. Moreover, creating symbolic links on Windows may require
--   privileges unavailable to users outside the Administrators group.
--   Portable programs that use symbolic links should take both into
--   consideration.
--   
--   On Windows, the function is implemented using
--   CreateSymbolicLink. Since 1.3.3.0, the
--   SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE flag is included
--   if supported by the operating system. On POSIX, the function uses
--   symlink and is therefore atomic.
--   
--   Windows-specific errors: This operation may fail with
--   permissionErrorType if the user lacks the privileges to create
--   symbolic links. It may also fail with illegalOperationErrorType
--   if the file system does not support symbolic links.
createFileLink :: FilePath -> FilePath -> IO ()

-- | Create a directory symbolic link. The target path can be either
--   absolute or relative and need not refer to an existing directory. The
--   order of arguments follows the POSIX convention.
--   
--   To remove an existing directory symbolic link, use
--   removeDirectoryLink.
--   
--   Although the distinction between file symbolic links and
--   directory symbolic links does not exist on POSIX systems, on
--   Windows this is an intrinsic property of every symbolic link and
--   cannot be changed without recreating the link. A file symbolic link
--   that actually points to a directory will fail to dereference and vice
--   versa. Moreover, creating symbolic links on Windows may require
--   privileges unavailable to users outside the Administrators group.
--   Portable programs that use symbolic links should take both into
--   consideration.
--   
--   On Windows, the function is implemented using
--   CreateSymbolicLink with
--   SYMBOLIC_LINK_FLAG_DIRECTORY. Since 1.3.3.0, the
--   SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE flag is also
--   included if supported by the operating system. On POSIX, this is an
--   alias for createFileLink and is therefore atomic.
--   
--   Windows-specific errors: This operation may fail with
--   permissionErrorType if the user lacks the privileges to create
--   symbolic links. It may also fail with illegalOperationErrorType
--   if the file system does not support symbolic links.
createDirectoryLink :: FilePath -> FilePath -> IO ()

-- | Remove an existing directory symbolic link.
--   
--   On Windows, this is an alias for removeDirectory. On POSIX
--   systems, this is an alias for removeFile.
--   
--   See also: removeFile, which can remove an existing file
--   symbolic link.
removeDirectoryLink :: FilePath -> IO ()

-- | Check whether an existing path is a symbolic link. If
--   path is a regular file or directory, False is
--   returned. If path does not exist or is otherwise
--   inaccessible, an exception is thrown (see below).
--   
--   On Windows, this checks for FILE_ATTRIBUTE_REPARSE_POINT. In
--   addition to symbolic links, the function also returns true on junction
--   points. On POSIX systems, this checks for S_IFLNK.
--   
--   The operation may fail with:
--   
--   
--   
- isDoesNotExistError if the symbolic link does not exist;
--   or
--   
- isPermissionError if the user is not permitted to read the
--   symbolic link.
--   
pathIsSymbolicLink :: FilePath -> IO Bool

-- | Retrieve the target path of either a file or directory symbolic link.
--   The returned path may not be absolute, may not exist, and may not even
--   be a valid path.
--   
--   On Windows systems, this calls DeviceIoControl with
--   FSCTL_GET_REPARSE_POINT. In addition to symbolic links, the
--   function also works on junction points. On POSIX systems, this calls
--   readlink.
--   
--   Windows-specific errors: This operation may fail with
--   illegalOperationErrorType if the file system does not support
--   symbolic links.
getSymbolicLinkTarget :: FilePath -> IO FilePath

-- | Obtain the time at which the file or directory was last accessed.
--   
--   The operation may fail with:
--   
--   
--   
- isPermissionError if the user is not permitted to read the
--   access time; or
--   
- isDoesNotExistError if the file or directory does not
--   exist.
--   
--   
--   Caveat for POSIX systems: This function returns a timestamp with
--   sub-second resolution only if this package is compiled against
--   unix-2.6.0.0 or later and the underlying filesystem supports
--   them.
getAccessTime :: FilePath -> IO UTCTime

-- | Obtain the time at which the file or directory was last modified.
--   
--   The operation may fail with:
--   
--   
--   
- isPermissionError if the user is not permitted to read the
--   modification time; or
--   
- isDoesNotExistError if the file or directory does not
--   exist.
--   
--   
--   Caveat for POSIX systems: This function returns a timestamp with
--   sub-second resolution only if this package is compiled against
--   unix-2.6.0.0 or later and the underlying filesystem supports
--   them.
getModificationTime :: FilePath -> IO UTCTime

-- | Change the time at which the file or directory was last accessed.
--   
--   The operation may fail with:
--   
--   
--   
- isPermissionError if the user is not permitted to alter the
--   access time; or
--   
- isDoesNotExistError if the file or directory does not
--   exist.
--   
--   
--   Some caveats for POSIX systems:
--   
--   
--   
- Not all systems support utimensat, in which case the
--   function can only emulate the behavior by reading the modification
--   time and then setting both the access and modification times together.
--   On systems where utimensat is supported, the access time is
--   set atomically with nanosecond precision.
--   
- If compiled against a version of unix prior to
--   2.7.0.0, the function would not be able to set timestamps
--   with sub-second resolution. In this case, there would also be loss of
--   precision in the modification time.
--   
setAccessTime :: FilePath -> UTCTime -> IO ()

-- | Change the time at which the file or directory was last modified.
--   
--   The operation may fail with:
--   
--   
--   
- isPermissionError if the user is not permitted to alter the
--   modification time; or
--   
- isDoesNotExistError if the file or directory does not
--   exist.
--   
- InvalidArgument on FAT32 file system if the time is before
--   DOS Epoch (1 January 1980).
--   
--   
--   Some caveats for POSIX systems:
--   
--   
--   
- Not all systems support utimensat, in which case the
--   function can only emulate the behavior by reading the access time and
--   then setting both the access and modification times together. On
--   systems where utimensat is supported, the modification time
--   is set atomically with nanosecond precision.
--   
- If compiled against a version of unix prior to
--   2.7.0.0, the function would not be able to set timestamps
--   with sub-second resolution. In this case, there would also be loss of
--   precision in the access time.
--   
setModificationTime :: FilePath -> UTCTime -> IO ()

-- | Returns the current user's home directory.
--   
--   The directory returned is expected to be writable by the current user,
--   but note that it isn't generally considered good practice to store
--   application-specific data here; use getXdgDirectory or
--   getAppUserDataDirectory instead.
--   
--   On Unix, getHomeDirectory behaves as follows:
--   
--   
--   
- Returns $HOME env variable if set (including to an empty
--   string).
--   
- Otherwise uses home directory returned by getpwuid_r
--   using the UID of the current proccesses user. This basically reads the
--   etcpasswd file. An empty home directory field is considered
--   valid.
--   
--   
--   On Windows, the system is queried for a suitable path; a typical path
--   might be C:/Users/<user>.
--   
--   The operation may fail with:
--   
--   
--   
- UnsupportedOperation The operating system has no notion
--   of home directory.
--   
- isDoesNotExistError The home directory for the current user
--   does not exist, or cannot be found.
--   
getHomeDirectory :: IO FilePath

-- | Obtain the paths to special directories for storing user-specific
--   application data, configuration, and cache files, conforming to the
--   XDG Base Directory Specification. Compared with
--   getAppUserDataDirectory, this function provides a more
--   fine-grained hierarchy as well as greater flexibility for the user.
--   
--   On Windows, XdgData and XdgConfig usually map to the
--   same directory unless overridden.
--   
--   Refer to the docs of XdgDirectory for more details.
--   
--   The second argument is usually the name of the application. Since it
--   will be integrated into the path, it must consist of valid path
--   characters. Note: if the second argument is an absolute path, it will
--   just return the second argument.
--   
--   Note: The directory may not actually exist, in which case you would
--   need to create it with file mode 700 (i.e. only accessible by
--   the owner).
--   
--   As of 1.3.5.0, the environment variable is ignored if set to a
--   relative path, per revised XDG Base Directory Specification. See
--   #100.
getXdgDirectory :: XdgDirectory -> FilePath -> IO FilePath

-- | Similar to getXdgDirectory but retrieves the entire list of XDG
--   directories.
--   
--   On Windows, XdgDataDirs and XdgConfigDirs usually map to
--   the same list of directories unless overridden.
--   
--   Refer to the docs of XdgDirectoryList for more details.
getXdgDirectoryList :: XdgDirectoryList -> IO [FilePath]

-- | Obtain the path to a special directory for storing user-specific
--   application data (traditional Unix location). Newer applications may
--   prefer the the XDG-conformant location provided by
--   getXdgDirectory (migration guide).
--   
--   The argument is usually the name of the application. Since it will be
--   integrated into the path, it must consist of valid path characters.
--   
--   
--   
- On Unix-like systems, the path is
--   ~/.<app>.
--   
- On Windows, the path is %APPDATA%/<app>
--   (e.g.
--   C:/Users/<user>/AppData/Roaming/<app>)
--   
--   
--   Note: the directory may not actually exist, in which case you would
--   need to create it. It is expected that the parent directory exists and
--   is writable.
--   
--   The operation may fail with:
--   
--   
--   
- UnsupportedOperation The operating system has no notion
--   of application-specific data directory.
--   
- isDoesNotExistError The home directory for the current user
--   does not exist, or cannot be found.
--   
getAppUserDataDirectory :: FilePath -> IO FilePath

-- | Returns the current user's document directory.
--   
--   The directory returned is expected to be writable by the current user,
--   but note that it isn't generally considered good practice to store
--   application-specific data here; use getXdgDirectory or
--   getAppUserDataDirectory instead.
--   
--   On Unix, getUserDocumentsDirectory returns the value of the
--   HOME environment variable. On Windows, the system is queried
--   for a suitable path; a typical path might be
--   C:/Users/<user>/Documents.
--   
--   The operation may fail with:
--   
--   
--   
- UnsupportedOperation The operating system has no notion
--   of document directory.
--   
- isDoesNotExistError The document directory for the current
--   user does not exist, or cannot be found.
--   
getUserDocumentsDirectory :: IO FilePath

-- | Returns the current directory for temporary files.
--   
--   On Unix, getTemporaryDirectory returns the value of the
--   TMPDIR environment variable or "/tmp" if the variable isn't
--   defined. On Windows, the function checks for the existence of
--   environment variables in the following order and uses the first path
--   found:
--   
--   
--   
- TMP environment variable.
--   
- TEMP environment variable.
--   
- USERPROFILE environment variable.
--   
- The Windows directory
--   
--   
--   The operation may fail with:
--   
--   
--   
- UnsupportedOperation The operating system has no notion
--   of temporary directory.
--   
--   
--   The function doesn't verify whether the path exists.
getTemporaryDirectory :: IO FilePath
isSymbolicLink :: FilePath -> IO Bool

-- | Remove any trailing path separators
--   
--   
--   dropTrailingPathSeparator "file/test/" == "file/test"
--             dropTrailingPathSeparator "/" == "/"
--   Windows:  dropTrailingPathSeparator "\\" == "\\"
--   Posix:    not (hasTrailingPathSeparator (dropTrailingPathSeparator x)) || isDrive x
--   
dropTrailingPathSeparator :: FilePath -> FilePath

-- | Contract a filename, based on a relative path. Note that the resulting
--   path will never introduce .. paths, as the presence of
--   symlinks means ../b may not reach a/b if it starts
--   from a/c. For a worked example see this blog post.
--   
--   The corresponding makeAbsolute function can be found in
--   System.Directory.
--   
--   
--            makeRelative "/directory" "/directory/file.ext" == "file.ext"
--            Valid x => makeRelative (takeDirectory x) x `equalFilePath` takeFileName x
--            makeRelative x x == "."
--            Valid x y => equalFilePath x y || (isRelative x && makeRelative y x == x) || equalFilePath (y </> makeRelative y x) x
--   Windows: makeRelative "C:\\Home" "c:\\home\\bob" == "bob"
--   Windows: makeRelative "C:\\Home" "c:/home/bob" == "bob"
--   Windows: makeRelative "C:\\Home" "D:\\Home\\Bob" == "D:\\Home\\Bob"
--   Windows: makeRelative "C:\\Home" "C:Home\\Bob" == "C:Home\\Bob"
--   Windows: makeRelative "/Home" "/home/bob" == "bob"
--   Windows: makeRelative "/" "//" == "//"
--   Posix:   makeRelative "/Home" "/home/bob" == "/home/bob"
--   Posix:   makeRelative "/home/" "/home/bob/foo/bar" == "bob/foo/bar"
--   Posix:   makeRelative "/fred" "bob" == "bob"
--   Posix:   makeRelative "/file/test" "/file/test/fred" == "fred"
--   Posix:   makeRelative "/file/test" "/file/test/fred/" == "fred/"
--   Posix:   makeRelative "some/path" "some/path/a/b/c" == "a/b/c"
--   
makeRelative :: FilePath -> FilePath -> FilePath

-- | Combine two paths with a path separator. If the second path starts
--   with a path separator or a drive letter, then it returns the second.
--   The intention is that readFile (dir </> file)
--   will access the same file as setCurrentDirectory dir; readFile
--   file.
--   
--   
--   Posix:   "/directory" </> "file.ext" == "/directory/file.ext"
--   Windows: "/directory" </> "file.ext" == "/directory\\file.ext"
--            "directory" </> "/file.ext" == "/file.ext"
--   Valid x => (takeDirectory x </> takeFileName x) `equalFilePath` x
--   
--   
--   Combined:
--   
--   
--   Posix:   "/" </> "test" == "/test"
--   Posix:   "home" </> "bob" == "home/bob"
--   Posix:   "x:" </> "foo" == "x:/foo"
--   Windows: "C:\\foo" </> "bar" == "C:\\foo\\bar"
--   Windows: "home" </> "bob" == "home\\bob"
--   
--   
--   Not combined:
--   
--   
--   Posix:   "home" </> "/bob" == "/bob"
--   Windows: "home" </> "C:\\bob" == "C:\\bob"
--   
--   
--   Not combined (tricky):
--   
--   On Windows, if a filepath starts with a single slash, it is relative
--   to the root of the current drive. In [1], this is (confusingly)
--   referred to as an absolute path. The current behavior of
--   </> is to never combine these forms.
--   
--   
--   Windows: "home" </> "/bob" == "/bob"
--   Windows: "home" </> "\\bob" == "\\bob"
--   Windows: "C:\\home" </> "\\bob" == "\\bob"
--   
--   
--   On Windows, from [1]: "If a file name begins with only a disk
--   designator but not the backslash after the colon, it is interpreted as
--   a relative path to the current directory on the drive with the
--   specified letter." The current behavior of </> is to
--   never combine these forms.
--   
--   
--   Windows: "D:\\foo" </> "C:bar" == "C:bar"
--   Windows: "C:\\foo" </> "C:bar" == "C:bar"
--   
(</>) :: FilePath -> FilePath -> FilePath
infixr 5 </>
curry3 :: ((a, b, c) -> d) -> a -> b -> c -> d
uncurry3 :: (a -> b -> c -> d) -> (a, b, c) -> d
first3 :: (a, b, c) -> a
second3 :: (a, b, c) -> b
third3 :: (a, b, c) -> c
headDef :: a -> [a] -> a
lastDef :: a -> [a] -> a

-- | Computation system cmd returns the exit code produced when
--   the operating system runs the shell command cmd.
--   
--   This computation may fail with one of the following IOErrorType
--   exceptions:
--   
--   
--   
- PermissionDenied The process has insufficient
--   privileges to perform the operation.
--   
- ResourceExhausted Insufficient resources are
--   available to perform the operation.
--   
- UnsupportedOperation The implementation does not
--   support system calls.
--   
--   
--   On Windows, system passes the command to the Windows command
--   interpreter (CMD.EXE or COMMAND.COM), hence Unixy
--   shell tricks will not work.
--   
--   On Unix systems, see waitForProcess for the meaning of exit
--   codes when the process died as the result of a signal.
system :: String -> IO ExitCode

-- | Waits for the specified process to terminate, and returns its exit
--   code. On Unix systems, may throw UserInterrupt when using
--   delegate_ctlc.
--   
--   GHC Note: in order to call waitForProcess without blocking
--   all the other threads in the system, you must compile the program with
--   -threaded.
--   
--   Note that it is safe to call waitForProcess for the same
--   process in multiple threads. When the process ends, threads blocking
--   on this call will wake in FIFO order. When using delegate_ctlc
--   and the process is interrupted, only the first waiting thread will
--   throw UserInterrupt.
--   
--   (Since: 1.2.0.0) On Unix systems, a negative value
--   ExitFailure -signum indicates that the child
--   was terminated by signal signum. The signal numbers
--   are platform-specific, so to test for a specific signal use the
--   constants provided by System.Posix.Signals in the unix
--   package. Note: core dumps are not reported, use
--   System.Posix.Process if you need this detail.
waitForProcess :: ProcessHandle -> IO ExitCode

-- | This is the most general way to spawn an external process. The process
--   can be a command line to be executed by a shell or a raw command with
--   a list of arguments. The stdin, stdout, and stderr streams of the new
--   process may individually be attached to new pipes, to existing
--   Handles, or just inherited from the parent (the default.)
--   
--   The details of how to create the process are passed in the
--   CreateProcess record. To make it easier to construct a
--   CreateProcess, the functions proc and shell are
--   supplied that fill in the fields with default values which can be
--   overriden as needed.
--   
--   createProcess returns (mb_stdin_hdl,
--   mb_stdout_hdl, mb_stderr_hdl, ph), where
--   
--   
--   
- if std_in == CreatePipe, then
--   mb_stdin_hdl will be Just h, where
--   h is the write end of the pipe connected to the child
--   process's stdin.
--   
- otherwise, mb_stdin_hdl == Nothing
--   
--   
--   Similarly for mb_stdout_hdl and
--   mb_stderr_hdl.
--   
--   For example, to execute a simple ls command:
--   
--   
--   r <- createProcess (proc "ls" [])
--   
--   
--   To create a pipe from which to read the output of ls:
--   
--   
--   (_, Just hout, _, _) <-
--       createProcess (proc "ls" []){ std_out = CreatePipe }
--   
--   
--   To also set the directory in which to run ls:
--   
--   
--   (_, Just hout, _, _) <-
--       createProcess (proc "ls" []){ cwd = Just "/home/bob",
--                                     std_out = CreatePipe }
--   
--   
--   Note that Handles provided for std_in,
--   std_out, or std_err via the UseHandle
--   constructor will be closed by calling this function. This is not
--   always the desired behavior. In cases where you would like to leave
--   the Handle open after spawning the child process, please use
--   createProcess_ instead. All created Handles are
--   initially in text mode; if you need them to be in binary mode then use
--   hSetBinaryMode.
--   
--   ph contains a handle to the running process. On
--   Windows use_process_jobs can be set in CreateProcess in order
--   to create a Win32 Job object to monitor a process tree's progress. If
--   it is set then that job is also returned inside ph.
--   ph can be used to kill all running sub-processes. This
--   feature has been available since 1.5.0.0.
createProcess :: CreateProcess -> IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)

-- | This function is almost identical to createProcess. The only
--   differences are:
--   
--   
--   
- Handles provided via UseHandle are not closed
--   automatically.
--   
- This function takes an extra String argument to be used
--   in creating error messages.
--   
--   
--   This function has been available from the
--   System.Process.Internals module for some time, and is part of
--   the System.Process module since version 1.2.1.0.
createProcess_ :: String -> CreateProcess -> IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)

-- | Create a pipe for interprocess communication and return a
--   (readEnd, writeEnd) Handle pair.
--   
--   
--   
- WinIO Support
--   
--   
--   When this function is used with WinIO enabled it's the caller's
--   responsibility to register the handles with the I/O manager. If this
--   is not done the operation will deadlock. Association can be done as
--   follows:
--   
--   
--   #if defined(IO_MANAGER_WINIO)
--   import GHC.IO.SubSystem ((!))
--   import GHC.IO.Handle.Windows (handleToHANDLE)
--   import GHC.Event.Windows (associateHandle')
--   #endif
--   
--   ...
--   
--   #if defined (IO_MANAGER_WINIO)
--   return () ! (do
--     associateHandle' =handleToHANDLE <handle)
--   #endif
--   
--   
--   Only associate handles that you are in charge of read/writing to. Do
--   not associate handles passed to another process. It's the process's
--   reponsibility to register the handle if it supports async access.
createPipe :: IO (Handle, Handle)

-- | Create a pipe for interprocess communication and return a
--   (readEnd, writeEnd) FD pair.
createPipeFd :: IO (FD, FD)

-- | Sends an interrupt signal to the process group of the given process.
--   
--   On Unix systems, it sends the group the SIGINT signal.
--   
--   On Windows systems, it generates a CTRL_BREAK_EVENT and will only work
--   for processes created using createProcess and setting the
--   create_group flag
interruptProcessGroupOf :: ProcessHandle -> IO ()

-- | Construct a CreateProcess record for passing to
--   createProcess, representing a raw command with arguments.
--   
--   See RawCommand for precise semantics of the specified
--   FilePath.
proc :: FilePath -> [String] -> CreateProcess

-- | Construct a CreateProcess record for passing to
--   createProcess, representing a command to be passed to the
--   shell.
shell :: String -> CreateProcess

-- | A bracket-style resource handler for createProcess.
--   
--   Does automatic cleanup when the action finishes. If there is an
--   exception in the body then it ensures that the process gets terminated
--   and any CreatePipe Handles are closed. In particular
--   this means that if the Haskell thread is killed (e.g.
--   killThread), that the external process is also terminated.
--   
--   e.g.
--   
--   
--   withCreateProcess (proc cmd args) { ... }  $ \stdin stdout stderr ph -> do
--     ...
--   
withCreateProcess :: CreateProcess -> (Maybe Handle -> Maybe Handle -> Maybe Handle -> ProcessHandle -> IO a) -> IO a

-- | Cleans up the process.
--   
--   This function is meant to be invoked from any application level
--   cleanup handler. It terminates the process, and closes any
--   CreatePipe handles.
cleanupProcess :: (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle) -> IO ()

-- | Creates a new process to run the specified raw command with the given
--   arguments. It does not wait for the program to finish, but returns the
--   ProcessHandle.
spawnProcess :: FilePath -> [String] -> IO ProcessHandle

-- | Creates a new process to run the specified shell command. It does not
--   wait for the program to finish, but returns the ProcessHandle.
spawnCommand :: String -> IO ProcessHandle

-- | Creates a new process to run the specified command with the given
--   arguments, and wait for it to finish. If the command returns a
--   non-zero exit code, an exception is raised.
--   
--   If an asynchronous exception is thrown to the thread executing
--   callProcess, the forked process will be terminated and
--   callProcess will wait (block) until the process has been
--   terminated.
callProcess :: FilePath -> [String] -> IO ()

-- | Creates a new process to run the specified shell command. If the
--   command returns a non-zero exit code, an exception is raised.
--   
--   If an asynchronous exception is thrown to the thread executing
--   callCommand, the forked process will be terminated and
--   callCommand will wait (block) until the process has been
--   terminated.
callCommand :: String -> IO ()

-- | readProcess forks an external process, reads its standard
--   output strictly, blocking until the process terminates, and returns
--   the output string. The external process inherits the standard error.
--   
--   If an asynchronous exception is thrown to the thread executing
--   readProcess, the forked process will be terminated and
--   readProcess will wait (block) until the process has been
--   terminated.
--   
--   Output is returned strictly, so this is not suitable for launching
--   processes that require interaction over the standard file streams.
--   
--   This function throws an IOException if the process
--   ExitCode is anything other than ExitSuccess. If instead
--   you want to get the ExitCode then use
--   readProcessWithExitCode.
--   
--   Users of this function should compile with -threaded if they
--   want other Haskell threads to keep running while waiting on the result
--   of readProcess.
--   
--   
--   > readProcess "date" [] []
--   "Thu Feb  7 10:03:39 PST 2008\n"
--   
--   
--   The arguments are:
--   
--   
--   
- The command to run, which must be in the $PATH, or an absolute or
--   relative path
--   
- A list of separate command line arguments to the program. See
--   RawCommand for further discussion of Windows semantics.
--   
- A string to pass on standard input to the forked process.
--   
readProcess :: FilePath -> [String] -> String -> IO String

-- | readCreateProcess works exactly like readProcess
--   except that it lets you pass CreateProcess giving better
--   flexibility.
--   
--   
--   > readCreateProcess ((shell "pwd") { cwd = Just "/etc/" }) ""
--   "/etc\n"
--   
--   
--   Note that Handles provided for std_in or
--   std_out via the CreateProcess record will be ignored.
readCreateProcess :: CreateProcess -> String -> IO String

-- | readProcessWithExitCode is like readProcess but with
--   two differences:
--   
--   
--   
- it returns the ExitCode of the process, and does not throw
--   any exception if the code is not ExitSuccess.
--   
- it reads and returns the output from process' standard error
--   handle, rather than the process inheriting the standard error
--   handle.
--   
--   
--   On Unix systems, see waitForProcess for the meaning of exit
--   codes when the process died as the result of a signal.
readProcessWithExitCode :: FilePath -> [String] -> String -> IO (ExitCode, String, String)

-- | readCreateProcessWithExitCode works exactly like
--   readProcessWithExitCode except that it lets you pass
--   CreateProcess giving better flexibility.
--   
--   Note that Handles provided for std_in,
--   std_out, or std_err via the CreateProcess record
--   will be ignored.
readCreateProcessWithExitCode :: CreateProcess -> String -> IO (ExitCode, String, String)

-- | Given a program p and arguments args,
--   showCommandForUser p args returns a string
--   suitable for pasting into /bin/sh (on Unix systems) or
--   CMD.EXE (on Windows).
showCommandForUser :: FilePath -> [String] -> String

-- | Returns the PID (process ID) of a subprocess.
--   
--   Nothing is returned if the handle was already closed. Otherwise
--   a PID is returned that remains valid as long as the handle is open.
--   The operating system may reuse the PID as soon as the last handle to
--   the process is closed.
getPid :: ProcessHandle -> IO (Maybe Pid)

-- | Returns the PID (process ID) of the current process. On POSIX systems,
--   this calls getProcessID from System.Posix.Process in the
--   unix package. On Windows, this calls
--   getCurrentProcessId from System.Win32.Process in the
--   Win32 package.
getCurrentPid :: IO Pid

-- | This is a non-blocking version of waitForProcess. If the
--   process is still running, Nothing is returned. If the process
--   has exited, then Just e is returned where e
--   is the exit code of the process.
--   
--   On Unix systems, see waitForProcess for the meaning of exit
--   codes when the process died as the result of a signal. May throw
--   UserInterrupt when using delegate_ctlc.
getProcessExitCode :: ProcessHandle -> IO (Maybe ExitCode)

-- | Attempts to terminate the specified process. This function should not
--   be used under normal circumstances - no guarantees are given regarding
--   how cleanly the process is terminated. To check whether the process
--   has indeed terminated, use getProcessExitCode.
--   
--   On Unix systems, terminateProcess sends the process the SIGTERM
--   signal. On Windows systems, if use_process_jobs is True
--   then the Win32 TerminateJobObject function is called to kill
--   all processes associated with the job and passing the exit code of 1
--   to each of them. Otherwise if use_process_jobs is False
--   then the Win32 TerminateProcess function is called, passing
--   an exit code of 1.
--   
--   Note: on Windows, if the process was a shell command created by
--   createProcess with shell, or created by
--   runCommand or runInteractiveCommand, then
--   terminateProcess will only terminate the shell, not the command
--   itself. On Unix systems, both processes are in a process group and
--   will be terminated together.
terminateProcess :: ProcessHandle -> IO ()

-- | Runs a command using the shell.
runCommand :: String -> IO ProcessHandle

-- | Runs a raw command, optionally specifying Handles from which to
--   take the stdin, stdout and stderr channels
--   for the new process (otherwise these handles are inherited from the
--   current process).
--   
--   Any Handles passed to runProcess are placed immediately
--   in the closed state.
--   
--   Note: consider using the more general createProcess instead of
--   runProcess.
runProcess :: FilePath -> [String] -> Maybe FilePath -> Maybe [(String, String)] -> Maybe Handle -> Maybe Handle -> Maybe Handle -> IO ProcessHandle

-- | Runs a command using the shell, and returns Handles that may be
--   used to communicate with the process via its stdin,
--   stdout, and stderr respectively.
runInteractiveCommand :: String -> IO (Handle, Handle, Handle, ProcessHandle)

-- | Runs a raw command, and returns Handles that may be used to
--   communicate with the process via its stdin, stdout
--   and stderr respectively.
--   
--   For example, to start a process and feed a string to its stdin:
--   
--   
--   (inp,out,err,pid) <- runInteractiveProcess "..."
--   forkIO (hPutStr inp str)
--   
runInteractiveProcess :: FilePath -> [String] -> Maybe FilePath -> Maybe [(String, String)] -> IO (Handle, Handle, Handle, ProcessHandle)

-- | The computation rawSystem cmd args runs
--   the operating system command cmd in such a way that it
--   receives as arguments the args strings exactly as
--   given, with no funny escaping or shell meta-syntax expansion. It will
--   therefore behave more portably between operating systems than
--   system.
--   
--   The return codes and possible failures are the same as for
--   system.
rawSystem :: String -> [String] -> IO ExitCode

-- | The character that separates directories. In the case where more than
--   one character is possible, pathSeparator is the 'ideal' one.
--   
--   
--   Windows: pathSeparator == '\\'
--   Posix:   pathSeparator ==  '/'
--   isPathSeparator pathSeparator
--   
pathSeparator :: Char

-- | The list of all possible separators.
--   
--   
--   Windows: pathSeparators == ['\\', '/']
--   Posix:   pathSeparators == ['/']
--   pathSeparator `elem` pathSeparators
--   
pathSeparators :: [Char]

-- | Rather than using (== pathSeparator), use this. Test
--   if something is a path separator.
--   
--   
--   isPathSeparator a == (a `elem` pathSeparators)
--   
isPathSeparator :: Char -> Bool

-- | Is the character a file separator?
--   
--   
--   isSearchPathSeparator a == (a == searchPathSeparator)
--   
isSearchPathSeparator :: Char -> Bool

-- | File extension character
--   
--   
--   extSeparator == '.'
--   
extSeparator :: Char

-- | Is the character an extension character?
--   
--   
--   isExtSeparator a == (a == extSeparator)
--   
isExtSeparator :: Char -> Bool

-- | Take a string, split it on the searchPathSeparator character.
--   Blank items are ignored on Windows, and converted to . on
--   Posix. On Windows path elements are stripped of quotes.
--   
--   Follows the recommendations in
--   http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html
--   
--   
--   Posix:   splitSearchPath "File1:File2:File3"  == ["File1","File2","File3"]
--   Posix:   splitSearchPath "File1::File2:File3" == ["File1",".","File2","File3"]
--   Windows: splitSearchPath "File1;File2;File3"  == ["File1","File2","File3"]
--   Windows: splitSearchPath "File1;;File2;File3" == ["File1","File2","File3"]
--   Windows: splitSearchPath "File1;\"File2\";File3" == ["File1","File2","File3"]
--   
splitSearchPath :: String -> [FilePath]

-- | Get a list of FILEPATHs in the $PATH variable.
getSearchPath :: IO [FilePath]

-- | Split on the extension. addExtension is the inverse.
--   
--   
--   splitExtension "/directory/path.ext" == ("/directory/path",".ext")
--   uncurry (<>) (splitExtension x) == x
--   Valid x => uncurry addExtension (splitExtension x) == x
--   splitExtension "file.txt" == ("file",".txt")
--   splitExtension "file" == ("file","")
--   splitExtension "file/file.txt" == ("file/file",".txt")
--   splitExtension "file.txt/boris" == ("file.txt/boris","")
--   splitExtension "file.txt/boris.ext" == ("file.txt/boris",".ext")
--   splitExtension "file/path.txt.bob.fred" == ("file/path.txt.bob",".fred")
--   splitExtension "file/path.txt/" == ("file/path.txt/","")
--   
splitExtension :: FilePath -> (String, String)

-- | Get the extension of a file, returns "" for no extension,
--   .ext otherwise.
--   
--   
--   takeExtension "/directory/path.ext" == ".ext"
--   takeExtension x == snd (splitExtension x)
--   Valid x => takeExtension (addExtension x "ext") == ".ext"
--   Valid x => takeExtension (replaceExtension x "ext") == ".ext"
--   
takeExtension :: FilePath -> String

-- | Remove the current extension and add another, equivalent to
--   replaceExtension.
--   
--   
--   "/directory/path.txt" -<.> "ext" == "/directory/path.ext"
--   "/directory/path.txt" -<.> ".ext" == "/directory/path.ext"
--   "foo.o" -<.> "c" == "foo.c"
--   
(-<.>) :: FilePath -> String -> FilePath
infixr 7 -<.>

-- | Set the extension of a file, overwriting one if already present,
--   equivalent to -<.>.
--   
--   
--   replaceExtension "/directory/path.txt" "ext" == "/directory/path.ext"
--   replaceExtension "/directory/path.txt" ".ext" == "/directory/path.ext"
--   replaceExtension "file.txt" ".bob" == "file.bob"
--   replaceExtension "file.txt" "bob" == "file.bob"
--   replaceExtension "file" ".bob" == "file.bob"
--   replaceExtension "file.txt" "" == "file"
--   replaceExtension "file.fred.bob" "txt" == "file.fred.txt"
--   replaceExtension x y == addExtension (dropExtension x) y
--   
replaceExtension :: FilePath -> String -> FilePath

-- | Add an extension, even if there is already one there, equivalent to
--   addExtension.
--   
--   
--   "/directory/path" <.> "ext" == "/directory/path.ext"
--   "/directory/path" <.> ".ext" == "/directory/path.ext"
--   
(<.>) :: FilePath -> String -> FilePath
infixr 7 <.>

-- | Remove last extension, and the "." preceding it.
--   
--   
--   dropExtension "/directory/path.ext" == "/directory/path"
--   dropExtension x == fst (splitExtension x)
--   
dropExtension :: FilePath -> FilePath

-- | Add an extension, even if there is already one there, equivalent to
--   <.>.
--   
--   
--   addExtension "/directory/path" "ext" == "/directory/path.ext"
--   addExtension "file.txt" "bib" == "file.txt.bib"
--   addExtension "file." ".bib" == "file..bib"
--   addExtension "file" ".bib" == "file.bib"
--   addExtension "/" "x" == "/.x"
--   addExtension x "" == x
--   Valid x => takeFileName (addExtension (addTrailingPathSeparator x) "ext") == ".ext"
--   Windows: addExtension "\\\\share" ".txt" == "\\\\share\\.txt"
--   
addExtension :: FilePath -> String -> FilePath

-- | Does the given filename have an extension?
--   
--   
--   hasExtension "/directory/path.ext" == True
--   hasExtension "/directory/path" == False
--   null (takeExtension x) == not (hasExtension x)
--   
hasExtension :: FilePath -> Bool

-- | Does the given filename have the specified extension?
--   
--   
--   "png" `isExtensionOf` "/directory/file.png" == True
--   ".png" `isExtensionOf` "/directory/file.png" == True
--   ".tar.gz" `isExtensionOf` "bar/foo.tar.gz" == True
--   "ar.gz" `isExtensionOf` "bar/foo.tar.gz" == False
--   "png" `isExtensionOf` "/directory/file.png.jpg" == False
--   "csv/table.csv" `isExtensionOf` "/data/csv/table.csv" == False
--   
isExtensionOf :: String -> FilePath -> Bool

-- | Drop the given extension from a FilePath, and the "."
--   preceding it. Returns Nothing if the FilePath does not have the
--   given extension, or Just and the part before the extension if
--   it does.
--   
--   This function can be more predictable than dropExtensions,
--   especially if the filename might itself contain . characters.
--   
--   
--   stripExtension "hs.o" "foo.x.hs.o" == Just "foo.x"
--   stripExtension "hi.o" "foo.x.hs.o" == Nothing
--   dropExtension x == fromJust (stripExtension (takeExtension x) x)
--   dropExtensions x == fromJust (stripExtension (takeExtensions x) x)
--   stripExtension ".c.d" "a.b.c.d"  == Just "a.b"
--   stripExtension ".c.d" "a.b..c.d" == Just "a.b."
--   stripExtension "baz"  "foo.bar"  == Nothing
--   stripExtension "bar"  "foobar"   == Nothing
--   stripExtension ""     x          == Just x
--   
stripExtension :: String -> FilePath -> Maybe FilePath

-- | Split on all extensions.
--   
--   
--   splitExtensions "/directory/path.ext" == ("/directory/path",".ext")
--   splitExtensions "file.tar.gz" == ("file",".tar.gz")
--   uncurry (<>) (splitExtensions x) == x
--   Valid x => uncurry addExtension (splitExtensions x) == x
--   splitExtensions "file.tar.gz" == ("file",".tar.gz")
--   
splitExtensions :: FilePath -> (FilePath, String)

-- | Drop all extensions.
--   
--   
--   dropExtensions "/directory/path.ext" == "/directory/path"
--   dropExtensions "file.tar.gz" == "file"
--   not $ hasExtension $ dropExtensions x
--   not $ any isExtSeparator $ takeFileName $ dropExtensions x
--   
dropExtensions :: FilePath -> FilePath

-- | Get all extensions.
--   
--   
--   takeExtensions "/directory/path.ext" == ".ext"
--   takeExtensions "file.tar.gz" == ".tar.gz"
--   
takeExtensions :: FilePath -> String

-- | Replace all extensions of a file with a new extension. Note that
--   replaceExtension and addExtension both work for adding
--   multiple extensions, so only required when you need to drop all
--   extensions first.
--   
--   
--   replaceExtensions "file.fred.bob" "txt" == "file.txt"
--   replaceExtensions "file.fred.bob" "tar.gz" == "file.tar.gz"
--   
replaceExtensions :: FilePath -> String -> FilePath

-- | Split a path into a drive and a path. On Posix, / is a Drive.
--   
--   
--   uncurry (<>) (splitDrive x) == x
--   Windows: splitDrive "file" == ("","file")
--   Windows: splitDrive "c:/file" == ("c:/","file")
--   Windows: splitDrive "c:\\file" == ("c:\\","file")
--   Windows: splitDrive "\\\\shared\\test" == ("\\\\shared\\","test")
--   Windows: splitDrive "\\\\shared" == ("\\\\shared","")
--   Windows: splitDrive "\\\\?\\UNC\\shared\\file" == ("\\\\?\\UNC\\shared\\","file")
--   Windows: splitDrive "\\\\?\\UNCshared\\file" == ("\\\\?\\","UNCshared\\file")
--   Windows: splitDrive "\\\\?\\d:\\file" == ("\\\\?\\d:\\","file")
--   Windows: splitDrive "/d" == ("","/d")
--   Posix:   splitDrive "/test" == ("/","test")
--   Posix:   splitDrive "//test" == ("//","test")
--   Posix:   splitDrive "test/file" == ("","test/file")
--   Posix:   splitDrive "file" == ("","file")
--   
splitDrive :: FilePath -> (FilePath, FilePath)

-- | Join a drive and the rest of the path.
--   
--   
--   Valid x => uncurry joinDrive (splitDrive x) == x
--   Windows: joinDrive "C:" "foo" == "C:foo"
--   Windows: joinDrive "C:\\" "bar" == "C:\\bar"
--   Windows: joinDrive "\\\\share" "foo" == "\\\\share\\foo"
--   Windows: joinDrive "/:" "foo" == "/:\\foo"
--   
joinDrive :: FilePath -> FilePath -> FilePath

-- | Get the drive from a filepath.
--   
--   
--   takeDrive x == fst (splitDrive x)
--   
takeDrive :: FilePath -> FilePath

-- | Delete the drive, if it exists.
--   
--   
--   dropDrive x == snd (splitDrive x)
--   
dropDrive :: FilePath -> FilePath

-- | Does a path have a drive.
--   
--   
--   not (hasDrive x) == null (takeDrive x)
--   Posix:   hasDrive "/foo" == True
--   Windows: hasDrive "C:\\foo" == True
--   Windows: hasDrive "C:foo" == True
--            hasDrive "foo" == False
--            hasDrive "" == False
--   
hasDrive :: FilePath -> Bool

-- | Is an element a drive
--   
--   
--   Posix:   isDrive "/" == True
--   Posix:   isDrive "/foo" == False
--   Windows: isDrive "C:\\" == True
--   Windows: isDrive "C:\\foo" == False
--            isDrive "" == False
--   
isDrive :: FilePath -> Bool

-- | Split a filename into directory and file. </> is the
--   inverse. The first component will often end with a trailing slash.
--   
--   
--   splitFileName "/directory/file.ext" == ("/directory/","file.ext")
--   Valid x => uncurry (</>) (splitFileName x) == x || fst (splitFileName x) == "./"
--   Valid x => isValid (fst (splitFileName x))
--   splitFileName "file/bob.txt" == ("file/", "bob.txt")
--   splitFileName "file/" == ("file/", "")
--   splitFileName "bob" == ("./", "bob")
--   Posix:   splitFileName "/" == ("/","")
--   Windows: splitFileName "c:" == ("c:","")
--   Windows: splitFileName "\\\\?\\A:\\fred" == ("\\\\?\\A:\\","fred")
--   Windows: splitFileName "\\\\?\\A:" == ("\\\\?\\A:","")
--   
splitFileName :: FilePath -> (String, String)

-- | Set the filename.
--   
--   
--   replaceFileName "/directory/other.txt" "file.ext" == "/directory/file.ext"
--   Valid x => replaceFileName x (takeFileName x) == x
--   
replaceFileName :: FilePath -> String -> FilePath

-- | Drop the filename. Unlike takeDirectory, this function will
--   leave a trailing path separator on the directory.
--   
--   
--   dropFileName "/directory/file.ext" == "/directory/"
--   dropFileName x == fst (splitFileName x)
--   
dropFileName :: FilePath -> FilePath

-- | Get the file name.
--   
--   
--   takeFileName "/directory/file.ext" == "file.ext"
--   takeFileName "test/" == ""
--   isSuffixOf (takeFileName x) x
--   takeFileName x == snd (splitFileName x)
--   Valid x => takeFileName (replaceFileName x "fred") == "fred"
--   Valid x => takeFileName (x </> "fred") == "fred"
--   Valid x => isRelative (takeFileName x)
--   
takeFileName :: FilePath -> FilePath

-- | Get the base name, without an extension or path.
--   
--   
--   takeBaseName "/directory/file.ext" == "file"
--   takeBaseName "file/test.txt" == "test"
--   takeBaseName "dave.ext" == "dave"
--   takeBaseName "" == ""
--   takeBaseName "test" == "test"
--   takeBaseName (addTrailingPathSeparator x) == ""
--   takeBaseName "file/file.tar.gz" == "file.tar"
--   
takeBaseName :: FilePath -> String

-- | Set the base name.
--   
--   
--   replaceBaseName "/directory/other.ext" "file" == "/directory/file.ext"
--   replaceBaseName "file/test.txt" "bob" == "file/bob.txt"
--   replaceBaseName "fred" "bill" == "bill"
--   replaceBaseName "/dave/fred/bob.gz.tar" "new" == "/dave/fred/new.tar"
--   Valid x => replaceBaseName x (takeBaseName x) == x
--   
replaceBaseName :: FilePath -> String -> FilePath

-- | Is an item either a directory or the last character a path separator?
--   
--   
--   hasTrailingPathSeparator "test" == False
--   hasTrailingPathSeparator "test/" == True
--   
hasTrailingPathSeparator :: FilePath -> Bool

-- | Add a trailing file path separator if one is not already present.
--   
--   
--   hasTrailingPathSeparator (addTrailingPathSeparator x)
--   hasTrailingPathSeparator x ==> addTrailingPathSeparator x == x
--   Posix:    addTrailingPathSeparator "test/rest" == "test/rest/"
--   
addTrailingPathSeparator :: FilePath -> FilePath

-- | Get the directory name, move up one level.
--   
--   
--             takeDirectory "/directory/other.ext" == "/directory"
--             isPrefixOf (takeDirectory x) x || takeDirectory x == "."
--             takeDirectory "foo" == "."
--             takeDirectory "/" == "/"
--             takeDirectory "/foo" == "/"
--             takeDirectory "/foo/bar/baz" == "/foo/bar"
--             takeDirectory "/foo/bar/baz/" == "/foo/bar/baz"
--             takeDirectory "foo/bar/baz" == "foo/bar"
--   Windows:  takeDirectory "foo\\bar" == "foo"
--   Windows:  takeDirectory "foo\\bar\\\\" == "foo\\bar"
--   Windows:  takeDirectory "C:\\" == "C:\\"
--   
takeDirectory :: FilePath -> FilePath

-- | Set the directory, keeping the filename the same.
--   
--   
--   replaceDirectory "root/file.ext" "/directory/" == "/directory/file.ext"
--   Valid x => replaceDirectory x (takeDirectory x) `equalFilePath` x
--   
replaceDirectory :: FilePath -> String -> FilePath

-- | An alias for </>.
combine :: FilePath -> FilePath -> FilePath

-- | Split a path by the directory separator.
--   
--   
--   splitPath "/directory/file.ext" == ["/","directory/","file.ext"]
--   concat (splitPath x) == x
--   splitPath "test//item/" == ["test//","item/"]
--   splitPath "test/item/file" == ["test/","item/","file"]
--   splitPath "" == []
--   Windows: splitPath "c:\\test\\path" == ["c:\\","test\\","path"]
--   Posix:   splitPath "/file/test" == ["/","file/","test"]
--   
splitPath :: FilePath -> [FilePath]

-- | Just as splitPath, but don't add the trailing slashes to each
--   element.
--   
--   
--            splitDirectories "/directory/file.ext" == ["/","directory","file.ext"]
--            splitDirectories "test/file" == ["test","file"]
--            splitDirectories "/test/file" == ["/","test","file"]
--   Windows: splitDirectories "C:\\test\\file" == ["C:\\", "test", "file"]
--            Valid x => joinPath (splitDirectories x) `equalFilePath` x
--            splitDirectories "" == []
--   Windows: splitDirectories "C:\\test\\\\\\file" == ["C:\\", "test", "file"]
--            splitDirectories "/test///file" == ["/","test","file"]
--   
splitDirectories :: FilePath -> [FilePath]

-- | Join path elements back together.
--   
--   
--   joinPath z == foldr (</>) "" z
--   joinPath ["/","directory/","file.ext"] == "/directory/file.ext"
--   Valid x => joinPath (splitPath x) == x
--   joinPath [] == ""
--   Posix: joinPath ["test","file","path"] == "test/file/path"
--   
joinPath :: [FilePath] -> FilePath

-- | Equality of two FILEPATHs. If you call
--   System.Directory.canonicalizePath first this has a much
--   better chance of working. Note that this doesn't follow symlinks or
--   DOSNAM~1s.
--   
--   Similar to normalise, this does not expand "..",
--   because of symlinks.
--   
--   
--            x == y ==> equalFilePath x y
--            normalise x == normalise y ==> equalFilePath x y
--            equalFilePath "foo" "foo/"
--            not (equalFilePath "/a/../c" "/c")
--            not (equalFilePath "foo" "/foo")
--   Posix:   not (equalFilePath "foo" "FOO")
--   Windows: equalFilePath "foo" "FOO"
--   Windows: not (equalFilePath "C:" "C:/")
--   
equalFilePath :: FilePath -> FilePath -> Bool

-- | Is a FilePath valid, i.e. could you create a file like it? This
--   function checks for invalid names, and invalid characters, but does
--   not check if length limits are exceeded, as these are typically
--   filesystem dependent.
--   
--   
--            isValid "" == False
--            isValid "\0" == False
--   Posix:   isValid "/random_ path:*" == True
--   Posix:   isValid x == not (null x)
--   Windows: isValid "c:\\test" == True
--   Windows: isValid "c:\\test:of_test" == False
--   Windows: isValid "test*" == False
--   Windows: isValid "c:\\test\\nul" == False
--   Windows: isValid "c:\\test\\prn.txt" == False
--   Windows: isValid "c:\\nul\\file" == False
--   Windows: isValid "\\\\" == False
--   Windows: isValid "\\\\\\foo" == False
--   Windows: isValid "\\\\?\\D:file" == False
--   Windows: isValid "foo\tbar" == False
--   Windows: isValid "nul .txt" == False
--   Windows: isValid " nul.txt" == True
--   
isValid :: FilePath -> Bool

-- | Take a FilePath and make it valid; does not change already valid
--   FILEPATHs.
--   
--   
--   isValid (makeValid x)
--   isValid x ==> makeValid x == x
--   makeValid "" == "_"
--   makeValid "file\0name" == "file_name"
--   Windows: makeValid "c:\\already\\/valid" == "c:\\already\\/valid"
--   Windows: makeValid "c:\\test:of_test" == "c:\\test_of_test"
--   Windows: makeValid "test*" == "test_"
--   Windows: makeValid "c:\\test\\nul" == "c:\\test\\nul_"
--   Windows: makeValid "c:\\test\\prn.txt" == "c:\\test\\prn_.txt"
--   Windows: makeValid "c:\\test/prn.txt" == "c:\\test/prn_.txt"
--   Windows: makeValid "c:\\nul\\file" == "c:\\nul_\\file"
--   Windows: makeValid "\\\\\\foo" == "\\\\drive"
--   Windows: makeValid "\\\\?\\D:file" == "\\\\?\\D:\\file"
--   Windows: makeValid "nul .txt" == "nul _.txt"
--   
makeValid :: FilePath -> FilePath

-- | Is a path relative, or is it fixed to the root?
--   
--   
--   Windows: isRelative "path\\test" == True
--   Windows: isRelative "c:\\test" == False
--   Windows: isRelative "c:test" == True
--   Windows: isRelative "c:\\" == False
--   Windows: isRelative "c:/" == False
--   Windows: isRelative "c:" == True
--   Windows: isRelative "\\\\foo" == False
--   Windows: isRelative "\\\\?\\foo" == False
--   Windows: isRelative "\\\\?\\UNC\\foo" == False
--   Windows: isRelative "/foo" == True
--   Windows: isRelative "\\foo" == True
--   Posix:   isRelative "test/path" == True
--   Posix:   isRelative "/test" == False
--   Posix:   isRelative "/" == False
--   
--   
--   According to [1]:
--   
--   
--   
- "A UNC name of any format [is never relative]."
--   
- "You cannot use the "\?" prefix with a relative path."
--   
isRelative :: FilePath -> Bool

-- | 
--   not . isRelative
--   
--   
--   
--   isAbsolute x == not (isRelative x)
--   
isAbsolute :: FilePath -> Bool

-- | Double-width-character-aware string truncation. Take as many
--   characters as possible from a string without exceeding the specified
--   width. Eg takeWidth 3 "りんご" = "り".
takeWidth :: Int -> String -> String
charWidth :: Char -> Int

-- | Construction of Pos from Int. The function throws
--   InvalidPosException when given a non-positive argument.
mkPos :: Int -> Pos

-- | Extract Int from Pos.
unPos :: Pos -> Int

-- | Construct initial position (line 1, column 1) given name of source
--   file.
initialPos :: FilePath -> SourcePos

-- | Pretty-print a SourcePos.
sourcePosPretty :: SourcePos -> String

-- | The inverse of ExceptT.
runExceptT :: ExceptT e m a -> m (Either e a)

-- | A shortcut for creating Timeout values
mkTimeout :: Integer -> Timeout

-- | Create a named group of test cases or other groups
testGroup :: TestName -> [TestTree] -> TestTree

-- | Like after, but accepts the pattern as a syntax tree instead of
--   a string. Useful for generating a test tree programmatically.
--   
--   
Examples
--   
--   Only match on the test's own name, ignoring the group names:
--   
--   
--   after_ AllFinish (EQ (Field NF) (StringLit "Bar")) $
--      
--   
--   
--   testCase "A test that depends on Foo.Bar" $ ... 
after_ :: DependencyType -> Expr -> TestTree -> TestTree

-- | The after combinator declares dependencies between tests.
--   
--   If a TestTree is wrapped in after, the tests in this
--   tree will not run until certain other tests («dependencies») have
--   finished. These dependencies are specified using an AWK pattern (see
--   the «Patterns» section in the README).
--   
--   Moreover, if the DependencyType argument is set to
--   AllSucceed and at least one dependency has failed, this test
--   tree will not run at all.
--   
--   Tasty does not check that the pattern matches any tests (let alone the
--   correct set of tests), so it is on you to supply the right pattern.
--   
--   
Examples
--   
--   The following test will be executed only after all tests that contain
--   Foo anywhere in their path finish.
--   
--   
--   after AllFinish "Foo" $
--      
--   
--   
--   testCase "A test that depends on Foo.Bar" $ ... 
--   
--   Note, however, that our test also happens to contain Foo as
--   part of its name, so it also matches the pattern and becomes a
--   dependency of itself. This will result in a DependencyLoop
--   exception. To avoid this, either change the test name so that it
--   doesn't mention Foo or make the pattern more specific.
--   
--   You can use AWK patterns, for instance, to specify the full path to
--   the dependency.
--   
--   
--   after AllFinish "$0 == \"Tests.Foo.Bar\"" $
--      
--   
--   
--   testCase "A test that depends on Foo.Bar" $ ... 
--   
--   Or only specify the dependency's own name, ignoring the group names:
--   
--   
--   after AllFinish "$NF == \"Bar\"" $
--      
--   
--   
--   testCase "A test that depends on Foo.Bar" $ ... 
after :: DependencyType -> String -> TestTree -> TestTree

-- | This ingredient doesn't do anything apart from registering additional
--   options.
--   
--   The option values can be accessed using askOption.
includingOptions :: [OptionDescription] -> Ingredient

-- | Parse the command line arguments and run the tests using the provided
--   ingredient list.
--   
--   When the tests finish, this function calls exitWith with the
--   exit code that indicates whether any tests have failed. See
--   defaultMain for details.
defaultMainWithIngredients :: [Ingredient] -> TestTree -> IO ()

-- | List of the default ingredients. This is what defaultMain uses.
--   
--   At the moment it consists of listingTests and
--   consoleTestReporter.
defaultIngredients :: [Ingredient]

-- | Locally adjust the option value for the given test subtree
adjustOption :: IsOption v => (v -> v) -> TestTree -> TestTree

-- | Locally set the option value for the given test subtree
localOption :: IsOption v => v -> TestTree -> TestTree

-- | Customize the test tree based on the run-time options
askOption :: IsOption v => (v -> TestTree) -> TestTree

-- | Acquire the resource to run this test (sub)tree and release it
--   afterwards
withResource :: IO a -> (a -> IO ()) -> (IO a -> TestTree) -> TestTree
toRegex :: Text -> Either RegexError Regexp
toRegexCI :: Text -> Either RegexError Regexp
toRegex' :: Text -> Regexp
toRegexCI' :: Text -> Regexp

-- | Test whether a Regexp matches a String. This is an alias for
--   matchTest for consistent naming.
regexMatch :: Regexp -> String -> Bool

-- | Tests whether a Regexp matches a Text.
--   
--   This currently unpacks the Text to a String an works on that. This is
--   due to a performance bug in regex-tdfa (#9), which may or may not be
--   relevant here.
regexMatchText :: Regexp -> Text -> Bool

-- | Return a (possibly empty) list of match groups derived by applying the
--   Regex to a Text.
regexMatchTextGroups :: Regexp -> Text -> [Text]

-- | A memoising version of regexReplace. Caches the result for each search
--   pattern, replacement pattern, target string tuple. This won't generate
--   a regular expression parsing error since that is pre-compiled
--   nowadays, but there can still be a runtime error from the replacement
--   pattern, eg with a backreference referring to a nonexistent match
--   group.
regexReplace :: Regexp -> Replacement -> String -> Either RegexError String
regexReplaceUnmemo :: Regexp -> Replacement -> String -> Either RegexError String
regexReplaceAllBy :: Regexp -> (String -> String) -> String -> String
fromEFDay :: EFDay -> Day
modifyEFDay :: (Day -> Day) -> EFDay -> EFDay
isBalanceSheetAccountType :: AccountType -> Bool
isIncomeStatementAccountType :: AccountType -> Bool

-- | Check whether the first argument is a subtype of the second: either
--   equal or one of the defined subtypes.
isAccountSubtypeOf :: AccountType -> AccountType -> Bool
isDecimalMark :: Char -> Bool

-- | Compare two MixedAmounts, substituting 0 for the quantity of any
--   missing commodities in either.
maCompare :: MixedAmount -> MixedAmount -> Ordering
nulltransactionmodifier :: TransactionModifier
nullperiodictransaction :: PeriodicTransaction
nullpayeedeclarationinfo :: PayeeDeclarationInfo
nulltagdeclarationinfo :: TagDeclarationInfo
nullaccountdeclarationinfo :: AccountDeclarationInfo

-- | Convert Periods to exact DateSpans.
--   
--   
--   >>> periodAsDateSpan (MonthPeriod 2000 1) == DateSpan (Just $ Flex $ fromGregorian 2000 1 1) (Just $ Flex $ fromGregorian 2000 2 1)
--   True
--   
periodAsDateSpan :: Period -> DateSpan

-- | Convert DateSpans to Periods.
--   
--   
--   >>> dateSpanAsPeriod $ DateSpan (Just $ Exact $ fromGregorian 2000 1 1) (Just $ Exact $ fromGregorian 2000 2 1)
--   MonthPeriod 2000 1
--   
dateSpanAsPeriod :: DateSpan -> Period

-- | Convert PeriodBetweens to a more abstract period where possible.
--   
--   
--   >>> simplifyPeriod $ PeriodBetween (fromGregorian 1 1 1) (fromGregorian 2 1 1)
--   YearPeriod 1
--   
--   >>> simplifyPeriod $ PeriodBetween (fromGregorian 2000 10 1) (fromGregorian 2001 1 1)
--   QuarterPeriod 2000 4
--   
--   >>> simplifyPeriod $ PeriodBetween (fromGregorian 2000 2 1) (fromGregorian 2000 3 1)
--   MonthPeriod 2000 2
--   
--   >>> simplifyPeriod $ PeriodBetween (fromGregorian 2016 7 25) (fromGregorian 2016 8 1)
--   WeekPeriod 2016-07-25
--   
--   >>> simplifyPeriod $ PeriodBetween (fromGregorian 2000 1 1) (fromGregorian 2000 1 2)
--   DayPeriod 2000-01-01
--   
--   >>> simplifyPeriod $ PeriodBetween (fromGregorian 2000 2 28) (fromGregorian 2000 3 1)
--   PeriodBetween 2000-02-28 2000-03-01
--   
--   >>> simplifyPeriod $ PeriodBetween (fromGregorian 2000 2 29) (fromGregorian 2000 3 1)
--   DayPeriod 2000-02-29
--   
--   >>> simplifyPeriod $ PeriodBetween (fromGregorian 2000 12 31) (fromGregorian 2001 1 1)
--   DayPeriod 2000-12-31
--   
simplifyPeriod :: Period -> Period
isLastDayOfMonth :: (Eq a1, Eq a2, Num a1, Num a2) => Year -> a1 -> a2 -> Bool

-- | Is this period a "standard" period, referencing a particular day,
--   week, month, quarter, or year ? Periods of other durations, or
--   infinite duration, or not starting on a standard period boundary, are
--   not.
isStandardPeriod :: Period -> Bool

-- | The width of a period of this type when displayed.
periodTextWidth :: Period -> Int

-- | Render a period as a compact display string suitable for user output.
--   
--   
--   >>> showPeriod (WeekPeriod (fromGregorian 2016 7 25))
--   "2016-07-25W30"
--   
showPeriod :: Period -> Text

-- | Like showPeriod, but if it's a month period show just the 3 letter
--   month name abbreviation for the current locale.
showPeriodMonthAbbrev :: Period -> Text
periodStart :: Period -> Maybe Day
periodEnd :: Period -> Maybe Day

-- | Move a standard period to the following period of same duration.
--   Non-standard periods are unaffected.
periodNext :: Period -> Period

-- | Move a standard period to the preceding period of same duration.
--   Non-standard periods are unaffected.
periodPrevious :: Period -> Period

-- | Move a standard period to the following period of same duration,
--   staying within enclosing dates. Non-standard periods are unaffected.
periodNextIn :: DateSpan -> Period -> Period

-- | Move a standard period to the preceding period of same duration,
--   staying within enclosing dates. Non-standard periods are unaffected.
periodPreviousIn :: DateSpan -> Period -> Period

-- | Move a standard period stepwise so that it encloses the given date.
--   Non-standard periods are unaffected.
periodMoveTo :: Day -> Period -> Period

-- | Enlarge a standard period to the next larger enclosing standard
--   period, if there is one. Eg, a day becomes the enclosing week. A week
--   becomes whichever month the week's thursday falls into. A year becomes
--   all (unlimited). Non-standard periods (arbitrary dates, or open-ended)
--   are unaffected.
periodGrow :: Period -> Period

-- | Shrink a period to the next smaller standard period inside it,
--   choosing the subperiod which contains today's date if possible,
--   otherwise the first subperiod. It goes like this: unbounded periods
--   and nonstandard periods (between two arbitrary dates) -> current
--   year -> current quarter if it's in selected year, otherwise first
--   quarter of selected year -> current month if it's in selected
--   quarter, otherwise first month of selected quarter -> current week
--   if it's in selected month, otherwise first week of selected month
--   -> today if it's in selected week, otherwise first day of selected
--   week, unless that's in previous month, in which case first day of
--   month containing selected week. Shrinking a day has no effect.
periodShrink :: Day -> Period -> Period
mondayBefore :: Day -> Day
yearMonthContainingWeekStarting :: Day -> (Year, MonthOfYear)
quarterContainingMonth :: Integral a => a -> a
firstMonthOfQuarter :: Num a => a -> a
startOfFirstWeekInMonth :: Integer -> Int -> Day

-- | Pretty-print our custom parse errors. It is necessary to use this
--   instead of errorBundlePretty when custom parse errors are
--   thrown.
--   
--   This function intercepts our custom parse errors and applies final
--   adjustments (finalizeCustomError) before passing them to
--   errorBundlePretty. These adjustments are part of the
--   implementation of the behaviour of our custom parse errors.
--   
--   Note: We must ensure that the offset of the PosState of the
--   provided ParseErrorBundle is no larger than the offset
--   specified by a ErrorFailAt constructor. This is guaranteed if
--   this offset is set to 0 (that is, the beginning of the source file),
--   which is the case for ParseErrorBundles returned from
--   runParserT.
customErrorBundlePretty :: HledgerParseErrors -> String

-- | Convert a WideBuilder to a strict Text.
wbToText :: WideBuilder -> Text

-- | Convert a strict Text to a WideBuilder.
wbFromText :: Text -> WideBuilder

-- | Convert a WideBuilder to a String.
wbUnpack :: WideBuilder -> String
textCapitalise :: Text -> Text
textElideRight :: Int -> Text -> Text

-- | Remove trailing newlines/carriage returns.
textChomp :: Text -> Text

-- | Clip and pad a string to a minimum & maximum width, andor
--   leftright justify it. Works on multi-line strings too (but will
--   rewrite non-unix line endings).
formatText :: Bool -> Maybe Int -> Maybe Int -> Text -> Text

-- | Wrap a string in double quotes, and -prefix any embedded single
--   quotes, if it contains whitespace and is not already single- or
--   double-quoted.
quoteIfSpaced :: Text -> Text
textQuoteIfNeeded :: Text -> Text
escapeDoubleQuotes :: Text -> Text
escapeBackslash :: Text -> Text

-- | Strip one matching pair of single or double quotes on the ends of a
--   string.
stripquotes :: Text -> Text

-- | Remove all matching pairs of square brackets and parentheses from the
--   text.
textUnbracket :: Text -> Text

-- | Join several multi-line strings as side-by-side rectangular strings of
--   the same height, top-padded. Treats wide characters as double width.
textConcatTopPadded :: [Text] -> Text

-- | Join several multi-line strings as side-by-side rectangular strings of
--   the same height, bottom-padded. Treats wide characters as double
--   width.
textConcatBottomPadded :: [Text] -> Text

-- | General-purpose wide-char-aware single-line text layout function. It
--   can left- or right-pad a short string to a minimum width. It can left-
--   or right-clip a long string to a maximum width, optionally inserting
--   an ellipsis (the third argument). It clips and pads on the right when
--   the fourth argument is true, otherwise on the left. It treats wide
--   characters as double width.
fitText :: Maybe Int -> Maybe Int -> Bool -> Bool -> Text -> Text

-- | Double-width-character-aware string truncation. Take as many
--   characters as possible from a string without exceeding the specified
--   width. Eg textTakeWidth 3 "りんご" = "り".
textTakeWidth :: Int -> Text -> Text

-- | Add a prefix to each line of a string.
linesPrepend :: Text -> Text -> Text

-- | Add a prefix to the first line of a string, and a different prefix to
--   the remaining lines.
linesPrepend2 :: Text -> Text -> Text -> Text

-- | Join a list of Text Builders with a newline after each item.
unlinesB :: [Builder] -> Builder

-- | Read a decimal number from a Text. Assumes the input consists only of
--   digit characters.
readDecimal :: Text -> Integer
tests_Text :: TestTree

-- | Pretty show. An easier alias for pretty-simple's pShow. This will
--   probably show in colour if useColorOnStderr is true.
pshow :: Show a => a -> String

-- | Monochrome version of pshow. This will never show in colour.
pshow' :: Show a => a -> String

-- | Pretty print a showable value. An easier alias for pretty-simple's
--   pPrint. This will print in colour if useColorOnStderr is true.
pprint :: Show a => a -> IO ()

-- | Monochrome version of pprint. This will never print in colour.
pprint' :: Show a => a -> IO ()

-- | An alternative to ansi-terminal's getTerminalSize, based on the more
--   robust-looking terminal-size package. Tries to get stdout's terminal's
--   current height and width.
getTerminalHeightWidth :: IO (Maybe (Int, Int))
getTerminalHeight :: IO (Maybe Int)
getTerminalWidth :: IO (Maybe Int)

-- | Make sure our $LESS and $MORE environment variables contain R, to help
--   ensure the common pager less will show our ANSI output
--   properly. less uses $LESS by default, and $MORE when it is invoked as
--   more. What the original more program does, I'm not
--   sure. If $PAGER is configured to something else, this probably will
--   have no effect.
setupPager :: IO ()

-- | The command line arguments that were used at program startup. Uses
--   unsafePerformIO.
progArgs :: [String]

-- | Read the value of the -o/--output-file command line option provided at
--   program startup, if any, using unsafePerformIO.
outputFileOption :: Maybe String

-- | Check whether the -o/--output-file option has been used at program
--   startup with an argument other than "-", using unsafePerformIO.
hasOutputFile :: Bool

-- | Versions of some of text-ansi's string colors/styles which are more
--   careful to not print junk onscreen. These use our useColorOnStdout.
bold' :: String -> String
faint' :: String -> String
black' :: String -> String
red' :: String -> String
green' :: String -> String
yellow' :: String -> String
blue' :: String -> String
magenta' :: String -> String
cyan' :: String -> String
white' :: String -> String
brightBlack' :: String -> String
brightRed' :: String -> String
brightGreen' :: String -> String
brightYellow' :: String -> String
brightBlue' :: String -> String
brightMagenta' :: String -> String
brightCyan' :: String -> String
brightWhite' :: String -> String
rgb' :: Word8 -> Word8 -> Word8 -> String -> String

-- | Read the value of the --color or --colour command line option provided
--   at program startup using unsafePerformIO. If this option was not
--   provided, returns the empty string.
colorOption :: String

-- | Check the IO environment to see if ANSI colour codes should be used on
--   stdout. This is done using unsafePerformIO so it can be used anywhere,
--   eg in low-level debug utilities, which should be ok since we are just
--   reading. The logic is: use color if the program was started with
--   --color=yes|always or ( the program was not started with
--   --color=no|never and a NO_COLOR environment variable is not defined
--   and stdout supports ANSI color and -o/--output-file was not used, or
--   its value is "-" ).
useColorOnStdout :: Bool

-- | Like useColorOnStdout, but checks for ANSI color support on stderr,
--   and is not affected by -o/--output-file.
useColorOnStderr :: Bool

-- | Wrap a string in ANSI codes to set and reset foreground colour.
--   ColorIntensity is Dull or Vivid (ie normal and
--   bold). Color is one of Black, Red, Green,
--   Yellow, Blue, Magenta, Cyan,
--   White. Eg: color Dull Red "text".
color :: ColorIntensity -> Color -> String -> String

-- | Wrap a string in ANSI codes to set and reset background colour.
bgColor :: ColorIntensity -> Color -> String -> String

-- | Wrap a WideBuilder in ANSI codes to set and reset foreground colour.
colorB :: ColorIntensity -> Color -> WideBuilder -> WideBuilder

-- | Wrap a WideBuilder in ANSI codes to set and reset background colour.
bgColorB :: ColorIntensity -> Color -> WideBuilder -> WideBuilder

-- | Detect whether the terminal currently has a light background colour,
--   if possible, using unsafePerformIO. If the terminal is transparent,
--   its apparent light/darkness may be different.
terminalIsLight :: Maybe Bool

-- | Detect the terminal's current background lightness (0..1), if
--   possible, using unsafePerformIO. If the terminal is transparent, its
--   apparent lightness may be different.
terminalLightness :: Maybe Float

-- | Detect the terminal's current background colour, if possible, using
--   unsafePerformIO.
terminalBgColor :: Maybe (RGB Float)

-- | Detect the terminal's current foreground colour, if possible, using
--   unsafePerformIO.
terminalFgColor :: Maybe (RGB Float)

-- | Simpler alias for errorWithoutStackTrace
error' :: String -> a

-- | A version of errorWithoutStackTrace that adds a usage hint.
usageError :: String -> a

-- | Expand a tilde (representing home directory) at the start of a file
--   path. ~username is not supported. Can raise an error.
expandHomePath :: FilePath -> IO FilePath

-- | Given a current directory, convert a possibly relative, possibly
--   tilde-containing file path to an absolute one. ~username is not
--   supported. Leaves "-" unchanged. Can raise an error.
expandPath :: FilePath -> FilePath -> IO FilePath

-- | Like expandPath, but treats the expanded path as a glob, and returns
--   zero or more matched absolute file paths, alphabetically sorted.
expandGlob :: FilePath -> FilePath -> IO [FilePath]

-- | Given a list of existing file paths, sort them by modification time,
--   most recent first.
sortByModTime :: [FilePath] -> IO [FilePath]

-- | Like readFilePortably, but read all of the file before proceeding.
readFileStrictly :: FilePath -> IO Text

-- | Read text from a file, converting any rn line endings to n,, using the
--   system locale's text encoding, ignoring any utf8 BOM prefix (as seen
--   in paypal's 2018 CSV, eg) if that encoding is utf8.
readFilePortably :: FilePath -> IO Text

-- | Like readFilePortably, but read from standard input if the path is
--   "-".
readFileOrStdinPortably :: String -> IO Text
readHandlePortably :: Handle -> IO Text

-- | Like embedFile, but takes a path relative to the package directory.
embedFileRelative :: FilePath -> Q Exp
getCurrentLocalTime :: IO LocalTime
getCurrentZonedTime :: IO ZonedTime

-- | Assert any Left value.
assertLeft :: (HasCallStack, Eq b, Show b) => Either a b -> Assertion

-- | Assert any Right value.
assertRight :: (HasCallStack, Eq a, Show a) => Either a b -> Assertion

-- | Assert that this stateful parser runnable in IO successfully parses
--   all of the given input text, showing the parse error if it fails.
--   Suitable for hledger's JournalParser parsers.
assertParse :: (HasCallStack, Default st) => StateT st (ParsecT HledgerParseErrorData Text IO) a -> Text -> Assertion

-- | Assert a parser produces an expected value.
assertParseEq :: (HasCallStack, Eq a, Show a, Default st) => StateT st (ParsecT HledgerParseErrorData Text IO) a -> Text -> a -> Assertion

-- | Like assertParseEq, but transform the parse result with the given
--   function before comparing it.
assertParseEqOn :: (HasCallStack, Eq b, Show b, Default st) => StateT st (ParsecT HledgerParseErrorData Text IO) a -> Text -> (a -> b) -> b -> Assertion

-- | Assert that this stateful parser runnable in IO fails to parse the
--   given input text, with a parse error containing the given string.
assertParseError :: (HasCallStack, Eq a, Show a, Default st) => StateT st (ParsecT HledgerParseErrorData Text IO) a -> Text -> String -> Assertion

-- | Run a stateful parser in IO like assertParse, then assert that the
--   final state (the wrapped state, not megaparsec's internal state),
--   transformed by the given function, matches the given expected value.
assertParseStateOn :: (HasCallStack, Eq b, Show b, Default st) => StateT st (ParsecT HledgerParseErrorData Text IO) a -> Text -> (st -> b) -> b -> Assertion
assertParseE :: (HasCallStack, Eq a, Show a, Default st) => StateT st (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError IO)) a -> Text -> Assertion
assertParseEqE :: (Default st, Eq a, Show a, HasCallStack) => StateT st (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError IO)) a -> Text -> a -> Assertion
assertParseErrorE :: (Default st, Eq a, Show a, HasCallStack) => StateT st (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError IO)) a -> Text -> String -> Assertion

-- | The programs debug output verbosity. The default is 0 meaning no debug
--   output. The --debug command line flag sets it to 1, or
--   --debug=N sets it to a higher value (the = is required). Uses
--   unsafePerformIO. When running in GHCI, changing this requires
--   reloading this module.
debugLevel :: Int

-- | Pretty-trace a showable value before returning it. Like
--   Debug.Trace.traceShowId, but pretty-printing and easier to type.
ptrace :: Show a => a -> a

-- | Trace (print to stderr) a string if the global debug level is at or
--   above the specified level. At level 0, always prints. Otherwise, uses
--   unsafePerformIO.
traceAt :: Int -> String -> a -> a

-- | Trace (print to stderr) a showable value using a custom show function,
--   if the global debug level is at or above the specified level. At level
--   0, always prints. Otherwise, uses unsafePerformIO.
traceAtWith :: Int -> (a -> String) -> a -> a

-- | Pretty-print a label and a showable value to the console if the global
--   debug level is at or above the specified level. At level 0, always
--   prints. Otherwise, uses unsafePerformIO.
ptraceAt :: Show a => Int -> String -> a -> a

-- | Like ptraceAt, but convenient to insert in an IO monad and enforces
--   monadic sequencing.
ptraceAtIO :: (MonadIO m, Show a) => Int -> String -> a -> m ()

-- | Log a string to the debug log before returning the second argument.
--   Uses unsafePerformIO.
traceLog :: String -> a -> a

-- | Log a string to the debug log before returning the second argument, if
--   the global debug level is at or above the specified level. At level 0,
--   always logs. Otherwise, uses unsafePerformIO.
traceLogAt :: Int -> String -> a -> a

-- | Like traceLog but sequences properly in IO.
traceLogIO :: MonadIO m => String -> m ()

-- | Like traceLogAt, but convenient to use in IO.
traceLogAtIO :: MonadIO m => Int -> String -> m ()

-- | Log a value to the debug log with the given show function before
--   returning it.
traceLogWith :: (a -> String) -> a -> a

-- | Log a string to the debug log before returning the second argument, if
--   the global debug level is at or above the specified level. At level 0,
--   always logs. Otherwise, uses unsafePerformIO.
traceLogAtWith :: Int -> (a -> String) -> a -> a

-- | Pretty-log a label and showable value to the debug log, if the global
--   debug level is at or above the specified level. At level 0, always
--   prints. Otherwise, uses unsafePerformIO.
ptraceLogAt :: Show a => Int -> String -> a -> a

-- | Like ptraceAt, but convenient to insert in an IO monad and enforces
--   monadic sequencing.
ptraceLogAtIO :: (MonadIO m, Show a) => Int -> String -> a -> m ()

-- | Trace or log a string depending on shouldLog, before returning the
--   second argument.
traceOrLog :: String -> a -> a

-- | Trace or log a string depending on shouldLog, when global debug level
--   is at or above the specified level, before returning the second
--   argument.
traceOrLogAt :: Int -> String -> a -> a

-- | Pretty-trace or log depending on shouldLog, when global debug level is
--   at or above the specified level.
ptraceOrLogAt :: Show a => Int -> String -> a -> a

-- | Like ptraceOrLogAt, but convenient in IO.
ptraceOrLogAtIO :: (MonadIO m, Show a) => Int -> String -> a -> m ()

-- | Trace or log, with a show function, depending on shouldLog.
traceOrLogAtWith :: Int -> (a -> String) -> a -> a

-- | Pretty-trace to stderr (or log to debug log) a label and showable
--   value, then return it.
dbg0 :: Show a => String -> a -> a

-- | Pretty-trace to stderr (or log to debug log) a label and showable
--   value if the --debug level is high enough, then return the value. Uses
--   unsafePerformIO.
dbg1 :: Show a => String -> a -> a
dbg2 :: Show a => String -> a -> a
dbg3 :: Show a => String -> a -> a
dbg4 :: Show a => String -> a -> a
dbg5 :: Show a => String -> a -> a
dbg6 :: Show a => String -> a -> a
dbg7 :: Show a => String -> a -> a
dbg8 :: Show a => String -> a -> a
dbg9 :: Show a => String -> a -> a

-- | Like dbg0, but also exit the program. Uses unsafePerformIO.
dbgExit :: Show a => String -> a -> a

-- | Like dbgN, but convenient to use in IO.
dbg0IO :: (MonadIO m, Show a) => String -> a -> m ()
dbg1IO :: (MonadIO m, Show a) => String -> a -> m ()
dbg2IO :: (MonadIO m, Show a) => String -> a -> m ()
dbg3IO :: (MonadIO m, Show a) => String -> a -> m ()
dbg4IO :: (MonadIO m, Show a) => String -> a -> m ()
dbg5IO :: (MonadIO m, Show a) => String -> a -> m ()
dbg6IO :: (MonadIO m, Show a) => String -> a -> m ()
dbg7IO :: (MonadIO m, Show a) => String -> a -> m ()
dbg8IO :: (MonadIO m, Show a) => String -> a -> m ()
dbg9IO :: (MonadIO m, Show a) => String -> a -> m ()

-- | Like dbgN, but taking a show function instead of a label.
dbg0With :: (a -> String) -> a -> a
dbg1With :: Show a => (a -> String) -> a -> a
dbg2With :: Show a => (a -> String) -> a -> a
dbg3With :: Show a => (a -> String) -> a -> a
dbg4With :: Show a => (a -> String) -> a -> a
dbg5With :: Show a => (a -> String) -> a -> a
dbg6With :: Show a => (a -> String) -> a -> a
dbg7With :: Show a => (a -> String) -> a -> a
dbg8With :: Show a => (a -> String) -> a -> a
dbg9With :: Show a => (a -> String) -> a -> a

-- | Helper for producing debug messages: concatenates a name (eg a
--   function name), short description of the value being logged, and
--   string representation of the value.
lbl_ :: String -> String -> String -> String

-- | Trace to stderr or log to debug log the provided label (if non-null)
--   and current parser state (position and next input), if the global
--   debug level is at or above the specified level. Uses unsafePerformIO.
dbgparse :: forall (m :: Type -> Type). Int -> String -> TextParser m ()

-- | Trace to stderr or log to debug log the provided label (if non-null)
--   and current parser state (position and next input). See also:
--   Hledger.Utils.Debug, megaparsec's dbg. Uses unsafePerformIO. XXX Can
--   be hard to make this evaluate.
traceOrLogParse :: forall (m :: Type -> Type). String -> TextParser m ()

-- | Render a pair of source positions in human-readable form, only
--   displaying the range of lines.
sourcePosPairPretty :: (SourcePos, SourcePos) -> String

-- | Backtracking choice, use this when alternatives share a prefix.
--   Consumes no input if all choices fail.
choice' :: forall (m :: Type -> Type) a. [TextParser m a] -> TextParser m a

-- | Backtracking choice, use this when alternatives share a prefix.
--   Consumes no input if all choices fail.
choiceInState :: forall s (m :: Type -> Type) a. [StateT s (ParsecT HledgerParseErrorData Text m) a] -> StateT s (ParsecT HledgerParseErrorData Text m) a
surroundedBy :: Applicative m => m openclose -> m a -> m a
parsewith :: Parsec e Text a -> Text -> Either (ParseErrorBundle Text e) a

-- | Run a text parser in the identity monad. See also: parseWithState.
runTextParser :: TextParser Identity a -> Text -> Either HledgerParseErrors a

-- | Run a text parser in the identity monad. See also: parseWithState.
rtp :: TextParser Identity a -> Text -> Either HledgerParseErrors a
parsewithString :: Parsec e String a -> String -> Either (ParseErrorBundle String e) a

-- | Run a stateful parser with some initial state on a text. See also:
--   runTextParser, runJournalParser.
parseWithState :: Monad m => st -> StateT st (ParsecT HledgerParseErrorData Text m) a -> Text -> m (Either HledgerParseErrors a)
parseWithState' :: Stream s => st -> StateT st (ParsecT e s Identity) a -> s -> Either (ParseErrorBundle s e) a
fromparse :: (Show t, Show (Token t), Show e) => Either (ParseErrorBundle t e) a -> a
parseerror :: (Show t, Show (Token t), Show e) => ParseErrorBundle t e -> a
showDateParseError :: (Show t, Show (Token t), Show e) => ParseErrorBundle t e -> String
isNewline :: Char -> Bool
nonspace :: forall (m :: Type -> Type). TextParser m Char
isNonNewlineSpace :: Char -> Bool
spacenonewline :: forall s (m :: Type -> Type). (Stream s, Char ~ Token s) => ParsecT HledgerParseErrorData s m Char
restofline :: forall (m :: Type -> Type). TextParser m String
skipNonNewlineSpaces :: forall s (m :: Type -> Type). (Stream s, Token s ~ Char) => ParsecT HledgerParseErrorData s m ()
skipNonNewlineSpaces1 :: forall s (m :: Type -> Type). (Stream s, Token s ~ Char) => ParsecT HledgerParseErrorData s m ()
skipNonNewlineSpaces' :: forall s (m :: Type -> Type). (Stream s, Token s ~ Char) => ParsecT HledgerParseErrorData s m Bool
eolof :: forall (m :: Type -> Type). TextParser m ()
capitalise :: String -> String
lowercase :: String -> String
uppercase :: String -> String

-- | Remove leading whitespace.
lstrip :: String -> String

-- | Remove trailing whitespace.
rstrip :: String -> String

-- | Strip the given starting and ending character from the start and end
--   of a string if both are present.
strip1Char :: Char -> Char -> String -> String

-- | Strip a run of zero or more characters matching the predicate from the
--   start and end of a string.
stripBy :: (Char -> Bool) -> String -> String

-- | Strip a single balanced enclosing pair of a character matching the
--   predicate from the start and end of a string.
strip1By :: (Char -> Bool) -> String -> String

-- | Remove all trailing newlines/carriage returns.
chomp :: String -> String

-- | Remove all trailing newline/carriage returns, leaving just one
--   trailing newline.
chomp1 :: String -> String

-- | Remove consecutive line breaks, replacing them with single space
singleline :: String -> String
stripbrackets :: String -> String
elideLeft :: Int -> String -> String
elideRight :: Int -> String -> String
underline :: String -> String

-- | Double-quote this string if it contains whitespace, single quotes or
--   double-quotes, escaping the quotes as needed.
quoteIfNeeded :: String -> String

-- | Single-quote this string if it contains whitespace or double-quotes.
--   Does not work for strings containing single quotes.
singleQuoteIfNeeded :: String -> String

-- | Try to single- and backslash-quote a string as needed to make it
--   usable as an argument on a (sh/bash) shell command line. At least,
--   well enough to handle common currency symbols, like $. Probably broken
--   in many ways.
--   
--   
--   >>> quoteForCommandLine "a"
--   "a"
--   
--   >>> quoteForCommandLine "\""
--   "'\"'"
--   
--   >>> quoteForCommandLine "$"
--   "'\\$'"
--   
quoteForCommandLine :: String -> String

-- | Quote-aware version of words - don't split on spaces which are inside
--   quotes. NB correctly handles "a'b" but not "'a'". Can raise
--   an error if parsing fails.
words' :: String -> [String]

-- | Quote-aware version of unwords - single-quote strings which contain
--   whitespace
unwords' :: [String] -> String

-- | Like strWidth, but also strips ANSI escape sequences before
--   calculating the width.
--   
--   This is no longer used in code, as widths are calculated before adding
--   ANSI escape sequences, but is being kept around for now.
strWidthAnsi :: String -> Int

-- | Alias for realLength.
strWidth :: String -> Int

-- | Strip ANSI escape sequences from a string.
--   
--   
--   >>> stripAnsi "\ESC[31m-1\ESC[m"
--   "-1"
--   
stripAnsi :: String -> String

-- | Apply a function the specified number of times, which should be > 0
--   (otherwise does nothing). Possibly uses O(n) stack ?
applyN :: Int -> (a -> a) -> a -> a

-- | Like mapM but uses sequence'.
mapM' :: Monad f => (a -> f b) -> [a] -> f [b]

-- | This is a version of sequence based on difference lists. It is
--   slightly faster but we mostly use it because it uses the heap instead
--   of the stack. This has the advantage that Neil Mitchell’s trick of
--   limiting the stack size to discover space leaks doesn’t show this as a
--   false positive.
sequence' :: Monad f => [f a] -> f [a]
curry2 :: ((a, b) -> c) -> a -> b -> c
uncurry2 :: (a -> b -> c) -> (a, b) -> c
curry4 :: ((a, b, c, d) -> e) -> a -> b -> c -> d -> e
uncurry4 :: (a -> b -> c -> d -> e) -> (a, b, c, d) -> e

-- | Total version of maximum, for integral types, giving 0 for an empty
--   list.
maximum' :: Integral a => [a] -> a

-- | Strict version of maximum that doesn’t leak space
maximumStrict :: Ord a => [a] -> a

-- | Strict version of minimum that doesn’t leak space
minimumStrict :: Ord a => [a] -> a
splitAtElement :: Eq a => a -> [a] -> [[a]]

-- | Strict version of sum that doesn’t leak space
sumStrict :: Num a => [a] -> a

-- | Get the leaves of this tree as a list. The topmost node ("root" in
--   hledger account trees) is not counted as a leaf.
treeLeaves :: Tree a -> [a]
first4 :: (a, b, c, d) -> a
second4 :: (a, b, c, d) -> b
third4 :: (a, b, c, d) -> c
fourth4 :: (a, b, c, d) -> d
first5 :: (a, b, c, d, e) -> a
second5 :: (a, b, c, d, e) -> b
third5 :: (a, b, c, d, e) -> c
fourth5 :: (a, b, c, d, e) -> d
fifth5 :: (a, b, c, d, e) -> e
first6 :: (a, b, c, d, e, f) -> a
second6 :: (a, b, c, d, e, f) -> b
third6 :: (a, b, c, d, e, f) -> c
fourth6 :: (a, b, c, d, e, f) -> d
fifth6 :: (a, b, c, d, e, f) -> e
sixth6 :: (a, b, c, d, e, f) -> f

-- | Convert a list of strings to a multi-line multi-column list fitting
--   within the given width. Not wide character aware.
multicol :: Int -> [String] -> String

-- | Find the number of digits of an Int.
numDigitsInt :: Integral a => Int -> a

-- | Find the number of digits of an Integer. The integer should not have
--   more digits than an Int can count. This is probably inefficient.
numDigitsInteger :: Integer -> Int

-- | Make classy lenses for Hledger options fields. This is intended to be
--   used with BalancingOpts, InputOpt, ReportOpts, ReportSpec, and
--   CliOpts. When run on X, it will create a typeclass named HasX (except
--   for ReportOpts, which will be named HasReportOptsNoUpdate) containing
--   all the lenses for that type. If the field name starts with an
--   underscore, the lens name will be created by stripping the underscore
--   from the front on the name. If the field name ends with an underscore,
--   the field name ends with an underscore, the lens name will be mostly
--   created by stripping the underscore, but a few names for which this
--   would create too many conflicts instead have a second underscore
--   appended. ReportOpts fields for which updating them requires updating
--   the query in ReportSpec are instead names by dropping the trailing
--   underscore and appending NoUpdate to the name, e.g. querystring_ ->
--   querystringNoUpdate.
--   
--   There are a few reasons for the complicated rules. - We have some
--   legacy field names ending in an underscore (e.g. value_) which we want
--   to temporarily accommodate, before eventually switching to a more
--   modern style (e.g. _rsReportOpts) - Certain fields in ReportOpts need
--   to update the enclosing ReportSpec when they are updated, and it is a
--   common programming error to forget to do this. We append NoUpdate to
--   those lenses which will not update the enclosing field, and reserve
--   the shorter name for manually define lenses (or at least something
--   lens-like) which will update the ReportSpec. cf. the lengthy
--   discussion here and in surrounding comments:
--   https://github.com/simonmichael/hledger/pull/1545#issuecomment-881974554
makeHledgerClassyLenses :: Name -> DecsQ
tests_Utils :: TestTree
mkRawOpts :: [(String, String)] -> RawOpts
overRawOpts :: ([(String, String)] -> [(String, String)]) -> RawOpts -> RawOpts
setopt :: String -> String -> RawOpts -> RawOpts
setboolopt :: String -> RawOpts -> RawOpts
unsetboolopt :: String -> RawOpts -> RawOpts
appendopts :: [(String, String)] -> RawOpts -> RawOpts

-- | Is the named flag present ?
boolopt :: String -> RawOpts -> Bool

-- | Like boolopt, except if the flag is repeated on the command line it
--   toggles the value. An even number of repetitions is equivalent to
--   none.
toggleopt :: String -> RawOpts -> Bool

-- | From a list of RawOpts, get the last one (ie the right-most on the
--   command line) for which the given predicate returns a Just value.
--   Useful for exclusive choice flags like --daily|--weekly|--quarterly...
--   
--   
--   >>> import Safe (readMay)
--   
--   >>> choiceopt Just (RawOpts [("a",""), ("b",""), ("c","")])
--   Just "c"
--   
--   >>> choiceopt (const Nothing) (RawOpts [("a","")])
--   Nothing
--   
--   >>> choiceopt readMay (RawOpts [("LT",""),("EQ",""),("Neither","")]) :: Maybe Ordering
--   Just EQ
--   
choiceopt :: (String -> Maybe a) -> RawOpts -> Maybe a

-- | Collects processed and filtered list of options preserving their order
--   
--   
--   >>> collectopts (const Nothing) (RawOpts [("x","")])
--   []
--   
--   >>> collectopts Just (RawOpts [("a",""),("b","")])
--   [("a",""),("b","")]
--   
collectopts :: ((String, String) -> Maybe a) -> RawOpts -> [a]
maybestringopt :: String -> RawOpts -> Maybe String
stringopt :: String -> RawOpts -> String
maybecharopt :: String -> RawOpts -> Maybe Char
listofstringopt :: String -> RawOpts -> [String]

-- | Reads the named option's Int argument, if it is present. An argument
--   that is too small or too large will raise an error.
maybeintopt :: String -> RawOpts -> Maybe Int

-- | Reads the named option's natural-number argument, if it is present. An
--   argument that is negative or too large will raise an error.
maybeposintopt :: String -> RawOpts -> Maybe Int

-- | Reads the named option's Int argument. If not present it will return
--   0. An argument that is too small or too large will raise an error.
intopt :: String -> RawOpts -> Int

-- | Reads the named option's natural-number argument. If not present it
--   will return 0. An argument that is negative or too large will raise an
--   error.
posintopt :: String -> RawOpts -> Int
showDate :: Day -> Text
showEFDate :: EFDay -> Text

-- | Render a datespan as a display string, abbreviating into a compact
--   form if possible. Warning, hides whether dates are Exact or Flex.
showDateSpan :: DateSpan -> Text

-- | Show a DateSpan with its begin/end dates, exact or flex.
showDateSpanDebug :: DateSpan -> String

-- | Like showDateSpan, but show month spans as just the abbreviated month
--   name in the current locale.
showDateSpanMonthAbbrev :: DateSpan -> Text

-- | Get the current local date.
getCurrentDay :: IO Day

-- | Get the current local month number.
getCurrentMonth :: IO Int

-- | Get the current local year.
getCurrentYear :: IO Integer
elapsedSeconds :: Fractional a => UTCTime -> UTCTime -> a
spanStart :: DateSpan -> Maybe Day
spanStartYear :: DateSpan -> Maybe Year
spanEndYear :: DateSpan -> Maybe Year

-- | Get the 0-2 years mentioned explicitly in a DateSpan.
spanYears :: DateSpan -> [Year]

-- | Get overall span enclosing multiple sequentially ordered spans. The
--   start and end date will be exact or flexible depending on the first
--   span's start date and last span's end date.
spansSpan :: [DateSpan] -> DateSpan

-- | Split a DateSpan into consecutive exact spans of the specified
--   Interval. If the first argument is true and the interval is Weeks,
--   Months, Quarters or Years, the start date will be adjusted backward if
--   needed to nearest natural interval boundary (a monday, first of month,
--   first of quarter or first of year). If no interval is specified, the
--   original span is returned. If the original span is the null date span,
--   ie unbounded, the null date span is returned. If the original span is
--   empty, eg if the end date is <= the start date, no spans are
--   returned.
--   
--   
Examples:
--   
--   
--   >>> let t i y1 m1 d1 y2 m2 d2 = splitSpan True i $ DateSpan (Just $ Flex $ fromGregorian y1 m1 d1) (Just $ Flex $ fromGregorian y2 m2 d2)
--   
--   >>> t NoInterval 2008 01 01 2009 01 01
--   [DateSpan 2008]
--   
--   >>> t (Quarters 1) 2008 01 01 2009 01 01
--   [DateSpan 2008Q1,DateSpan 2008Q2,DateSpan 2008Q3,DateSpan 2008Q4]
--   
--   >>> splitSpan True (Quarters 1) nulldatespan
--   [DateSpan ..]
--   
--   >>> t (Days 1) 2008 01 01 2008 01 01  -- an empty datespan
--   []
--   
--   >>> t (Quarters 1) 2008 01 01 2008 01 01
--   []
--   
--   >>> t (Months 1) 2008 01 01 2008 04 01
--   [DateSpan 2008-01,DateSpan 2008-02,DateSpan 2008-03]
--   
--   >>> t (Months 2) 2008 01 01 2008 04 01
--   [DateSpan 2008-01-01..2008-02-29,DateSpan 2008-03-01..2008-04-30]
--   
--   >>> t (Weeks 1) 2008 01 01 2008 01 15
--   [DateSpan 2007-12-31W01,DateSpan 2008-01-07W02,DateSpan 2008-01-14W03]
--   
--   >>> t (Weeks 2) 2008 01 01 2008 01 15
--   [DateSpan 2007-12-31..2008-01-13,DateSpan 2008-01-14..2008-01-27]
--   
--   >>> t (DayOfMonth 2) 2008 01 01 2008 04 01
--   [DateSpan 2007-12-02..2008-01-01,DateSpan 2008-01-02..2008-02-01,DateSpan 2008-02-02..2008-03-01,DateSpan 2008-03-02..2008-04-01]
--   
--   >>> t (WeekdayOfMonth 2 4) 2011 01 01 2011 02 15
--   [DateSpan 2010-12-09..2011-01-12,DateSpan 2011-01-13..2011-02-09,DateSpan 2011-02-10..2011-03-09]
--   
--   >>> t (DaysOfWeek [2]) 2011 01 01 2011 01 15
--   [DateSpan 2010-12-28..2011-01-03,DateSpan 2011-01-04..2011-01-10,DateSpan 2011-01-11..2011-01-17]
--   
--   >>> t (DayOfYear 11 29) 2011 10 01 2011 10 15
--   [DateSpan 2010-11-29..2011-11-28]
--   
--   >>> t (DayOfYear 11 29) 2011 12 01 2012 12 15
--   [DateSpan 2011-11-29..2012-11-28,DateSpan 2012-11-29..2013-11-28]
--   
splitSpan :: Bool -> Interval -> DateSpan -> [DateSpan]

-- | Construct a list of exact DateSpans from a list of boundaries,
--   which fit within a given range.
spansFromBoundaries :: Day -> [Day] -> [DateSpan]

-- | Count the days in a DateSpan, or if it is open-ended return Nothing.
daysInSpan :: DateSpan -> Maybe Integer

-- | Does the span include the given date ?
spanContainsDate :: DateSpan -> Day -> Bool

-- | Does the period include the given date ? (Here to avoid import cycle).
periodContainsDate :: Period -> Day -> Bool

-- | Group elements based on where they fall in a list of DateSpans
--   without gaps. The precondition is not checked.
groupByDateSpan :: Bool -> (a -> Day) -> [DateSpan] -> [a] -> [(DateSpan, [a])]

-- | Calculate the intersection of a number of datespans.
spansIntersect :: [DateSpan] -> DateSpan

-- | Calculate the intersection of two datespans.
--   
--   For non-intersecting spans, gives an empty span beginning on the
--   second's start date: >>> DateSpan (Just $ Flex $
--   fromGregorian 2018 01 01) (Just $ Flex $ fromGregorian 2018 01 03)
--   spanIntersect DateSpan (Just $ Flex $ fromGregorian 2018 01 03)
--   (Just $ Flex $ fromGregorian 2018 01 05) DateSpan
--   2018-01-03..2018-01-02
spanIntersect :: DateSpan -> DateSpan -> DateSpan

-- | Fill any unspecified dates in the first span with the dates from the
--   second one. Sort of a one-way spanIntersect.
spanDefaultsFrom :: DateSpan -> DateSpan -> DateSpan

-- | Calculate the union of a number of datespans.
spansUnion :: [DateSpan] -> DateSpan

-- | Calculate the union of two datespans.
spanUnion :: DateSpan -> DateSpan -> DateSpan

-- | Calculate the minimal DateSpan containing all of the given Days (in
--   the usual exclusive-end-date sense: beginning on the earliest, and
--   ending on the day after the latest).
daysSpan :: [Day] -> DateSpan

-- | Select the DateSpan containing a given Day, if any, from a given list
--   of DateSpans.
--   
--   If the DateSpans are non-overlapping, this returns the unique
--   containing DateSpan, if it exists. If the DateSpans are overlapping,
--   it will return the containing DateSpan with the latest start date, and
--   then latest end date.
latestSpanContaining :: [DateSpan] -> Day -> Maybe DateSpan

-- | Parse a period expression to an Interval and overall DateSpan using
--   the provided reference date, or return a parse error.
parsePeriodExpr :: Day -> Text -> Either HledgerParseErrors (Interval, DateSpan)

-- | Like parsePeriodExpr, but call error' on failure.
parsePeriodExpr' :: Day -> Text -> (Interval, DateSpan)

-- | Convert a smart date string to an explicit yyyy/mm/dd string using the
--   provided reference date, or raise an error.
fixSmartDateStr :: Day -> Text -> Text

-- | A safe version of fixSmartDateStr.
fixSmartDateStrEither :: Day -> Text -> Either HledgerParseErrors Text
fixSmartDateStrEither' :: Day -> Text -> Either HledgerParseErrors EFDay

-- | Convert a SmartDate to a specific date using the provided reference
--   date. This date will be exact or flexible depending on whether the day
--   was specified exactly. (Missing least-significant parts produces a
--   flex date.)
--   
--   
Examples:
--   
--   
--   >>> :set -XOverloadedStrings
--   
--   >>> let t = fixSmartDateStr (fromGregorian 2008 11 26)
--   
--   >>> t "0000-01-01"
--   "0000-01-01"
--   
--   >>> t "1999-12-02"
--   "1999-12-02"
--   
--   >>> t "1999.12.02"
--   "1999-12-02"
--   
--   >>> t "1999/3/2"
--   "1999-03-02"
--   
--   >>> t "19990302"
--   "1999-03-02"
--   
--   >>> t "2008/2"
--   "2008-02-01"
--   
--   >>> t "0020/2"
--   "0020-02-01"
--   
--   >>> t "1000"
--   "1000-01-01"
--   
--   >>> t "4/2"
--   "2008-04-02"
--   
--   >>> t "2"
--   "2008-11-02"
--   
--   >>> t "January"
--   "2008-01-01"
--   
--   >>> t "feb"
--   "2008-02-01"
--   
--   >>> t "today"
--   "2008-11-26"
--   
--   >>> t "yesterday"
--   "2008-11-25"
--   
--   >>> t "tomorrow"
--   "2008-11-27"
--   
--   >>> t "this day"
--   "2008-11-26"
--   
--   >>> t "last day"
--   "2008-11-25"
--   
--   >>> t "next day"
--   "2008-11-27"
--   
--   >>> t "this week"  -- last monday
--   "2008-11-24"
--   
--   >>> t "last week"  -- previous monday
--   "2008-11-17"
--   
--   >>> t "next week"  -- next monday
--   "2008-12-01"
--   
--   >>> t "this month"
--   "2008-11-01"
--   
--   >>> t "last month"
--   "2008-10-01"
--   
--   >>> t "next month"
--   "2008-12-01"
--   
--   >>> t "this quarter"
--   "2008-10-01"
--   
--   >>> t "last quarter"
--   "2008-07-01"
--   
--   >>> t "next quarter"
--   "2009-01-01"
--   
--   >>> t "this year"
--   "2008-01-01"
--   
--   >>> t "last year"
--   "2007-01-01"
--   
--   >>> t "next year"
--   "2009-01-01"
--   
--   
--   t "last wed" "2008-11-19" t "next friday" "2008-11-28" t "next
--   january" "2009-01-01"
--   
--   
--   >>> t "in 5 days"
--   "2008-12-01"
--   
--   >>> t "in 7 months"
--   "2009-06-01"
--   
--   >>> t "in -2 weeks"
--   "2008-11-10"
--   
--   >>> t "1 quarter ago"
--   "2008-07-01"
--   
--   >>> t "1 week ahead"
--   "2008-12-01"
--   
fixSmartDate :: Day -> SmartDate -> EFDay
prevday :: Day -> Day
intervalBoundaryBefore :: Interval -> Day -> Day

-- | Try to parse a couple of date string formats: `YYYY-MM-DD`,
--   `YYYY<i>MM</i>DD` or DD, with leading zeros required. For
--   internal use, not quite the same as the journal's "simple dates".
--   >>> parsedateM "20080203" Just 2008-02-03 >>>
--   parsedateM "20080203/" Nothing >>> parsedateM
--   "20080230" Nothing
parsedateM :: String -> Maybe Day

-- | Parse a date in any of the formats allowed in Ledger's period
--   expressions, and some others. Assumes any text in the parse stream has
--   been lowercased. Returns a SmartDate, to be converted to a full date
--   later (see fixSmartDate).
--   
--   Examples:
--   
--   
--   2004                                        (start of year, which must have 4+ digits)
--   2004/10                                     (start of month, which must be 1-12)
--   2004/10/1                                   (exact date, day must be 1-31)
--   10/1                                        (month and day in current year)
--   21                                          (day in current month)
--   october, oct                                (start of month in current year)
--   yesterday, today, tomorrow                  (-1, 0, 1 days from today)
--   last/this/next day/week/month/quarter/year  (-1, 0, 1 periods from the current period)
--   in n days/weeks/months/quarters/years       (n periods from the current period)
--   n days/weeks/months/quarters/years ago      (-n periods from the current period)
--   20181201                                    (8 digit YYYYMMDD with valid year month and day)
--   201812                                      (6 digit YYYYMM with valid year and month)
--   
--   
--   Note malformed digit sequences might give surprising results:
--   
--   
--   201813                                      (6 digits with an invalid month is parsed as start of 6-digit year)
--   20181301                                    (8 digits with an invalid month is parsed as start of 8-digit year)
--   20181232                                    (8 digits with an invalid day gives an error)
--   201801012                                   (9+ digits beginning with a valid YYYYMMDD gives an error)
--   
--   
--   Eg:
--   
--   YYYYMMDD is parsed as year-month-date if those parts are valid (>=4
--   digits, 1-12, and 1-31 respectively): >>> parsewith
--   (smartdate <* eof) "20181201" Right (SmartCompleteDate 2018-12-01)
--   
--   YYYYMM is parsed as year-month-01 if year and month are valid:
--   >>> parsewith (smartdate <* eof) "201804" Right
--   (SmartAssumeStart 2018 (Just 4))
--   
--   With an invalid month, it's parsed as a year: >>> parsewith
--   (smartdate <* eof) "201813" Right (SmartAssumeStart 201813 Nothing)
--   
--   A 9+ digit number beginning with valid YYYYMMDD gives an error:
--   >>> parsewith (smartdate <* eof) "201801012" Left (...)
--   
--   Big numbers not beginning with a valid YYYYMMDD are parsed as a year:
--   >>> parsewith (smartdate <* eof) "201813012" Right
--   (SmartAssumeStart 201813012 Nothing)
smartdate :: forall (m :: Type -> Type). TextParser m SmartDate
datesepchars :: String
datesepchar :: forall (m :: Type -> Type). TextParser m Char
isDateSepChar :: Char -> Bool

-- | Parse a year number from a Text, making sure that at least four digits
--   are used.
yearp :: forall (m :: Type -> Type). TextParser m Integer

-- | Parse a period expression, specifying a date span and optionally a
--   reporting interval. Requires a reference "today" date for resolving
--   any relative start/end dates (only; it is not needed for parsing the
--   reporting interval).
--   
--   
--   >>> let p = parsePeriodExpr (fromGregorian 2008 11 26)
--   
--   >>> p "from Aug to Oct"
--   Right (NoInterval,DateSpan 2008-08-01..2008-09-30)
--   
--   >>> p "aug to oct"
--   Right (NoInterval,DateSpan 2008-08-01..2008-09-30)
--   
--   >>> p "2009q2"
--   Right (NoInterval,DateSpan 2009Q2)
--   
--   >>> p "Q3"
--   Right (NoInterval,DateSpan 2008Q3)
--   
--   >>> p "every 3 days in Aug"
--   Right (Days 3,DateSpan 2008-08)
--   
--   >>> p "daily from aug"
--   Right (Days 1,DateSpan 2008-08-01..)
--   
--   >>> p "every week to 2009"
--   Right (Weeks 1,DateSpan ..2008-12-31)
--   
--   >>> p "every 2nd day of month"
--   Right (DayOfMonth 2,DateSpan ..)
--   
--   >>> p "every 2nd day"
--   Right (DayOfMonth 2,DateSpan ..)
--   
--   >>> p "every 2nd day 2009.."
--   Right (DayOfMonth 2,DateSpan 2009-01-01..)
--   
--   >>> p "every 2nd day 2009-"
--   Right (DayOfMonth 2,DateSpan 2009-01-01..)
--   
--   >>> p "every 29th Nov"
--   Right (DayOfYear 11 29,DateSpan ..)
--   
--   >>> p "every 29th nov ..2009"
--   Right (DayOfYear 11 29,DateSpan ..2008-12-31)
--   
--   >>> p "every nov 29th"
--   Right (DayOfYear 11 29,DateSpan ..)
--   
--   >>> p "every Nov 29th 2009.."
--   Right (DayOfYear 11 29,DateSpan 2009-01-01..)
--   
--   >>> p "every 11/29 from 2009"
--   Right (DayOfYear 11 29,DateSpan 2009-01-01..)
--   
--   >>> p "every 11/29 since 2009"
--   Right (DayOfYear 11 29,DateSpan 2009-01-01..)
--   
--   >>> p "every 2nd Thursday of month to 2009"
--   Right (WeekdayOfMonth 2 4,DateSpan ..2008-12-31)
--   
--   >>> p "every 1st monday of month to 2009"
--   Right (WeekdayOfMonth 1 1,DateSpan ..2008-12-31)
--   
--   >>> p "every tue"
--   Right (DaysOfWeek [2],DateSpan ..)
--   
--   >>> p "every 2nd day of week"
--   Right (DaysOfWeek [2],DateSpan ..)
--   
--   >>> p "every 2nd day of month"
--   Right (DayOfMonth 2,DateSpan ..)
--   
--   >>> p "every 2nd day"
--   Right (DayOfMonth 2,DateSpan ..)
--   
--   >>> p "every 2nd day 2009.."
--   Right (DayOfMonth 2,DateSpan 2009-01-01..)
--   
--   >>> p "every 2nd day of month 2009.."
--   Right (DayOfMonth 2,DateSpan 2009-01-01..)
--   
periodexprp :: forall (m :: Type -> Type). Day -> TextParser m (Interval, DateSpan)
nulldatespan :: DateSpan

-- | An exact datespan of zero length, that matches no date.
emptydatespan :: DateSpan
nulldate :: Day
tests_Dates :: TestTree
acctsepchar :: Char
acctsep :: Text
accountNameComponents :: AccountName -> [Text]
accountNameFromComponents :: [Text] -> AccountName
accountLeafName :: AccountName -> Text

-- | Truncate all account name components but the last to two characters.
accountSummarisedName :: AccountName -> Text

-- | Regular expressions matching common English top-level account names,
--   used as a fallback when account types are not declared.
assetAccountRegex :: Regexp
cashAccountRegex :: Regexp
liabilityAccountRegex :: Regexp
equityAccountRegex :: Regexp
conversionAccountRegex :: Regexp
revenueAccountRegex :: Regexp
expenseAccountRegex :: Regexp

-- | Try to guess an account's type from its name, matching common English
--   top-level account names.
accountNameInferType :: AccountName -> Maybe AccountType
accountNameType :: Map AccountName AccountType -> AccountName -> Maybe AccountType
accountNameLevel :: AccountName -> Int

-- | A top-level account prefixed to some accounts in budget reports.
--   Defined here so it can be ignored by accountNameDrop.
unbudgetedAccountName :: Text
accountNamePostingType :: AccountName -> PostingType
accountNameWithoutPostingType :: AccountName -> AccountName
accountNameWithPostingType :: PostingType -> AccountName -> AccountName

-- | Prefix one account name to another, preserving posting type indicators
--   like concatAccountNames.
joinAccountNames :: AccountName -> AccountName -> AccountName

-- | Join account names into one. If any of them has () or [] posting type
--   indicators, these (the first type encountered) will also be applied to
--   the resulting account name.
concatAccountNames :: [AccountName] -> AccountName

-- | Rewrite an account name using all matching aliases from the given
--   list, in sequence. Each alias sees the result of applying the previous
--   aliases. Or, return any error arising from a bad regular expression in
--   the aliases.
accountNameApplyAliases :: [AccountAlias] -> AccountName -> Either RegexError AccountName

-- | Memoising version of accountNameApplyAliases, maybe overkill.
accountNameApplyAliasesMemo :: [AccountAlias] -> AccountName -> Either RegexError AccountName

-- | Remove some number of account name components from the front of the
--   account name. If the special "unbudgeted" top-level account is
--   present, it is preserved and dropping affects the rest of the account
--   name.
accountNameDrop :: Int -> AccountName -> AccountName

-- | Sorted unique account names implied by these account names, ie these
--   plus all their parent accounts up to the root. Eg: ["a:b:c","d:e"]
--   -> ["a","a:b","a:b:c","d","d:e"]
expandAccountNames :: [AccountName] -> [AccountName]

-- | "a:b:c" -> ["a","a:b","a:b:c"]
expandAccountName :: AccountName -> [AccountName]

-- | 
--   
- "a:b:c","d:e" -> ["a","d"]
--   
topAccountNames :: [AccountName] -> [AccountName]

-- | "a:b:c" -> "a"
topAccountName :: AccountName -> AccountName
parentAccountName :: AccountName -> AccountName
parentAccountNames :: AccountName -> [AccountName]

-- | Is the first account a parent or other ancestor of (and not the same
--   as) the second ?
isAccountNamePrefixOf :: AccountName -> AccountName -> Bool
isSubAccountNameOf :: AccountName -> AccountName -> Bool

-- | From a list of account names, select those which are direct
--   subaccounts of the given account name.
subAccountNamesFrom :: [AccountName] -> AccountName -> [AccountName]

-- | Convert a list of account names to a tree, efficiently.
accountNameTreeFrom :: [AccountName] -> Tree AccountName

-- | Elide an account name to fit in the specified width. From the ledger
--   2.6 news:
--   
--   
--   What Ledger now does is that if an account name is too long, it will
--   start abbreviating the first parts of the account name down to two
--   letters in length.  If this results in a string that is still too
--   long, the front will be elided -- not the end.  For example:
--   
--     Expenses:Cash           ; OK, not too long
--     Ex:Wednesday:Cash       ; Expenses was abbreviated to fit
--     Ex:We:Afternoon:Cash    ; Expenses and Wednesday abbreviated
--     ; Expenses:Wednesday:Afternoon:Lunch:Snack:Candy:Chocolate:Cash
--     ..:Af:Lu:Sn:Ca:Ch:Cash  ; Abbreviated and elided!
--   
elideAccountName :: Int -> AccountName -> AccountName

-- | Keep only the first n components of an account name, where n is a
--   positive integer. If n is Just 0, returns the empty string, if n is
--   Nothing, return the full name.
clipAccountName :: Maybe Int -> AccountName -> AccountName

-- | Keep only the first n components of an account name, where n is a
--   positive integer. If n is Just 0, returns "...", if n is Nothing,
--   return the full name.
clipOrEllipsifyAccountName :: Maybe Int -> AccountName -> AccountName

-- | Escape an AccountName for use within a regular expression.
--   >>> putStr . T.unpack $ escapeName "First?!#$*?$(*) !^#*?
--   %)*!#" First?!#$*?$(*) !^#*? %)*!#
escapeName :: AccountName -> Text

-- | Convert an account name to a regular expression matching it and its
--   subaccounts.
accountNameToAccountRegex :: AccountName -> Regexp

-- | Convert an account name to a regular expression matching it and its
--   subaccounts, case insensitively.
accountNameToAccountRegexCI :: AccountName -> Regexp

-- | Convert an account name to a regular expression matching it but not
--   its subaccounts.
accountNameToAccountOnlyRegex :: AccountName -> Regexp

-- | Convert an account name to a regular expression matching it but not
--   its subaccounts, case insensitively.
accountNameToAccountOnlyRegexCI :: AccountName -> Regexp
accountNameToBeancount :: AccountName -> BeancountAccountName
beancountTopLevelAccounts :: IsString a => [a]
tests_AccountName :: TestTree

-- | Default line format for balance report: "%20(total)
--   %2(depth_spacer)%-(account)"
defaultBalanceLineFormat :: StringFormat

-- | Parse a string format specification, or return a parse error.
parseStringFormat :: Text -> Either String StringFormat
defaultStringFormatStyle :: [StringFormatComponent] -> StringFormat
tests_StringFormat :: TestTree

-- | Show space-containing commodity symbols quoted, as they are in a
--   journal.
showCommoditySymbol :: Text -> Text
isNonsimpleCommodityChar :: Char -> Bool
quoteCommoditySymbolIfNeeded :: Text -> Text

-- | Display amounts without colour, and with various other defaults.
noColour :: AmountDisplayOpts

-- | Display Amount and MixedAmount with no prices.
noCost :: AmountDisplayOpts

-- | Display Amount and MixedAmount on one line with no prices.
oneLine :: AmountDisplayOpts

-- | Display Amount and MixedAmount in a form suitable for CSV output.
csvDisplay :: AmountDisplayOpts

-- | The empty simple amount - a zero with no commodity symbol or cost and
--   the default amount display style.
nullamt :: Amount

-- | A special amount used as a marker, meaning "no explicit amount
--   provided here, infer it when needed". It is nullamt with commodity
--   symbol AUTO.
missingamt :: Amount
num :: Quantity -> Amount
hrs :: Quantity -> Amount
usd :: DecimalRaw Integer -> Amount
eur :: DecimalRaw Integer -> Amount
gbp :: DecimalRaw Integer -> Amount
per :: Quantity -> Amount
at :: Amount -> Amount -> Amount
(@@) :: Amount -> Amount -> Amount

-- | Convert an amount to the specified commodity, ignoring and discarding
--   any assigned prices and assuming an exchange rate of 1.
amountWithCommodity :: CommoditySymbol -> Amount -> Amount

-- | Convert a amount to its "cost" or "selling price" in another
--   commodity, using its attached transaction price if it has one. Notes:
--   
--   
--   
- price amounts must be MixedAmounts with exactly one component
--   Amount (or there will be a runtime error XXX)
--   
- price amounts should be positive in the Journal (though this is
--   currently not enforced)
--   
amountCost :: Amount -> Amount

-- | Strip all prices from an Amount
amountStripCost :: Amount -> Amount

-- | Divide an amount's quantity (and total cost, if any) by some number.
divideAmount :: Quantity -> Amount -> Amount

-- | Multiply an amount's quantity (and its total price, if it has one) by
--   a constant.
multiplyAmount :: Quantity -> Amount -> Amount

-- | Invert an amount (replace its quantity q with 1/q). (Its cost if any
--   is not changed, currently.)
invertAmount :: Amount -> Amount

-- | Is this amount negative ? The price is ignored.
isNegativeAmount :: Amount -> Bool

-- | Do this Amount and (and its total price, if it has one) appear to be
--   zero when rendered with its display precision ? The display precision
--   should usually have a specific value here; if unset, it will be
--   treated like NaturalPrecision.
amountLooksZero :: Amount -> Bool

-- | Is this Amount (and its total price, if it has one) exactly zero,
--   ignoring its display precision ?
amountIsZero :: Amount -> Bool

-- | Set an amount's display precision, flipped.
withPrecision :: Amount -> AmountPrecision -> Amount

-- | Set an amount's display precision.
amountSetPrecision :: AmountPrecision -> Amount -> Amount

-- | Ensure an amount's display precision is at least the given minimum
--   precision. Always sets an explicit Precision.
amountSetPrecisionMin :: Word8 -> Amount -> Amount

-- | Ensure an amount's display precision is at most the given maximum
--   precision. Always sets an explicit Precision.
amountSetPrecisionMax :: Word8 -> Amount -> Amount

-- | Increase an amount's display precision, if needed, to enough decimal
--   places to show it exactly (showing all significant decimal digits,
--   without trailing zeros). If the amount's display precision is unset,
--   it will be treated as precision 0.
amountSetFullPrecision :: Amount -> Amount

-- | We often want to display "infinite decimal" amounts rounded to some
--   readable number of digits, while still displaying amounts with a large
--   "non infinite" number of decimal digits (eg, 100 or 200 digits) in
--   full. This helper is like amountSetFullPrecision, but with some
--   refinements: 1. If the internal precision is the maximum (255),
--   indicating an infinite decimal, the display precision is set to a
--   smaller hard-coded default (8). 2. A maximum display precision can be
--   specified, setting a hard upper limit. This function always sets an
--   explicit display precision (ie, Precision n).
amountSetFullPrecisionOr :: Maybe Word8 -> Amount -> Amount

-- | The fallback display precision used when showing amounts representing
--   an infinite decimal.
defaultMaxPrecision :: Word8

-- | How many internal decimal digits are stored for this amount ?
amountInternalPrecision :: Amount -> Word8

-- | How many decimal digits will be displayed for this amount ?
amountDisplayPrecision :: Amount -> Word8

-- | Set an amount's internal decimal precision as well as its display
--   precision. This rounds or pads its Decimal quantity to the specified
--   number of decimal places. Rounding is done with Data.Decimal's default
--   roundTo function: "If the value ends in 5 then it is rounded to the
--   nearest even value (Banker's Rounding)".
setAmountInternalPrecision :: Word8 -> Amount -> Amount

-- | setAmountInternalPrecision with arguments flipped.
withInternalPrecision :: Amount -> Word8 -> Amount
canonicaliseAmount :: Map CommoditySymbol AmountStyle -> Amount -> Amount
styleAmount :: Map CommoditySymbol AmountStyle -> Amount -> Amount
amountSetStyles :: Map CommoditySymbol AmountStyle -> Amount -> Amount

-- | Set this amount style's rounding strategy when being applied to
--   amounts.
amountStyleSetRounding :: Rounding -> AmountStyle -> AmountStyle
amountStylesSetRounding :: Rounding -> Map CommoditySymbol AmountStyle -> Map CommoditySymbol AmountStyle

-- | Default amount style
amountstyle :: AmountStyle

-- | Reset this amount's display style to the default.
amountUnstyled :: Amount -> Amount

-- | Set (or clear) an amount's display decimal point.
setAmountDecimalPoint :: Maybe Char -> Amount -> Amount

-- | Set (or clear) an amount's display decimal point, flipped.
withDecimalPoint :: Amount -> Maybe Char -> Amount
showAmountCostB :: Amount -> WideBuilder

-- | Get the string representation of an amount, based on its commodity's
--   display settings. String representations equivalent to zero are
--   converted to just "0". The special "missing" amount is displayed as
--   the empty string.
--   
--   
--   showAmount = wbUnpack . showAmountB noColour
--   
showAmount :: Amount -> String

-- | Like showAmount but uses the given amount display options.
showAmountWith :: AmountDisplayOpts -> Amount -> String

-- | General function to generate a WideBuilder for an Amount, according
--   the supplied AmountDisplayOpts. This is the main function to use for
--   showing Amounts, constructing a builder; it can then be converted to a
--   Text with wbToText, or to a String with wbUnpack. Some special cases:
--   
--   
--   
- The special "missing" amount is displayed as the empty
--   string.
--   
- If an amount is showing digit group separators but no decimal
--   places, we force showing a decimal mark (with nothing after it) to
--   make it easier to parse correctly.
--   
showAmountB :: AmountDisplayOpts -> Amount -> WideBuilder

-- | Colour version. For a negative amount, adds ANSI codes to change the
--   colour, currently to hard-coded red.
--   
--   
--   cshowAmount = wbUnpack . showAmountB def{displayColour=True}
--   
cshowAmount :: Amount -> String

-- | Get the string representation of an amount, without any @ price.
--   
--   
--   showAmountWithoutPrice = wbUnpack . showAmountB noCost
--   
showAmountWithoutPrice :: Amount -> String

-- | Like showAmount, but show a zero amount's commodity if it has one.
--   
--   
--   showAmountWithZeroCommodity = wbUnpack . showAmountB noColour{displayZeryCommodity=True}
--   
showAmountWithZeroCommodity :: Amount -> String

-- | Get a string representation of an amount for debugging, appropriate to
--   the current debug level. 9 shows maximum detail.
showAmountDebug :: Amount -> String

-- | The empty mixed amount.
nullmixedamt :: MixedAmount

-- | A special mixed amount used as a marker, meaning "no explicit amount
--   provided here, infer it when needed".
missingmixedamt :: MixedAmount

-- | Does this MixedAmount include the "missing amount" marker ? Note:
--   currently does not test for equality with missingmixedamt, instead it
--   looks for missingamt among the Amounts. missingamt should always be
--   alone, but detect it even if not.
isMissingMixedAmount :: MixedAmount -> Bool

-- | Convert amounts in various commodities into a mixed amount.
mixed :: Foldable t => t Amount -> MixedAmount

-- | Create a MixedAmount from a single Amount.
mixedAmount :: Amount -> MixedAmount

-- | Add an Amount to a MixedAmount, normalising the result. Amounts with
--   different costs are kept separate.
maAddAmount :: MixedAmount -> Amount -> MixedAmount

-- | Add a collection of Amounts to a MixedAmount, normalising the result.
--   Amounts with different costs are kept separate.
maAddAmounts :: Foldable t => MixedAmount -> t Amount -> MixedAmount

-- | Negate mixed amount's quantities (and total prices, if any).
maNegate :: MixedAmount -> MixedAmount

-- | Sum two MixedAmount, keeping the cost of the first if any. Amounts
--   with different costs are kept separate (since 2021).
maPlus :: MixedAmount -> MixedAmount -> MixedAmount

-- | Subtract a MixedAmount from another. Amounts with different costs are
--   kept separate.
maMinus :: MixedAmount -> MixedAmount -> MixedAmount

-- | Sum a collection of MixedAmounts. Amounts with different costs are
--   kept separate.
maSum :: Foldable t => t MixedAmount -> MixedAmount

-- | Divide a mixed amount's quantities (and total prices, if any) by a
--   constant.
divideMixedAmount :: Quantity -> MixedAmount -> MixedAmount

-- | Multiply a mixed amount's quantities (and total prices, if any) by a
--   constant.
multiplyMixedAmount :: Quantity -> MixedAmount -> MixedAmount

-- | Calculate the average of some mixed amounts.
averageMixedAmounts :: [MixedAmount] -> MixedAmount

-- | Is this mixed amount negative, if we can tell that unambiguously? Ie
--   when normalised, are all individual commodity amounts negative ?
isNegativeMixedAmount :: MixedAmount -> Maybe Bool

-- | Does this mixed amount appear to be zero when rendered with its
--   display precision? See amountLooksZero.
mixedAmountLooksZero :: MixedAmount -> Bool

-- | Is this mixed amount exactly zero, ignoring its display precision? See
--   amountIsZero.
mixedAmountIsZero :: MixedAmount -> Bool

-- | Is this mixed amount exactly zero, ignoring its display precision?
--   
--   A convenient alias for mixedAmountIsZero.
maIsZero :: MixedAmount -> Bool

-- | Is this mixed amount non-zero, ignoring its display precision?
--   
--   A convenient alias for not . mixedAmountIsZero.
maIsNonZero :: MixedAmount -> Bool

-- | Get a mixed amount's component amounts, with some cleanups. The
--   following descriptions are old and possibly wrong:
--   
--   
--   
- amounts in the same commodity are combined unless they have
--   different prices or total prices
--   
- multiple zero amounts, all with the same non-null commodity, are
--   replaced by just the last of them, preserving the commodity and amount
--   style (all but the last zero amount are discarded)
--   
- multiple zero amounts with multiple commodities, or no
--   commodities, are replaced by one commodity-less zero amount
--   
- an empty amount list is replaced by one commodity-less zero
--   amount
--   
- the special "missing" mixed amount remains unchanged
--   
amounts :: MixedAmount -> [Amount]

-- | Get a mixed amount's component amounts, with some cleanups. This is a
--   new version of amounts, with updated descriptions and
--   optimised for print to show commodityful zeros.
--   
--   
--   
- If it contains the "missing amount" marker, only that is returned
--   (discarding any additional amounts).
--   
- Or if it contains any non-zero amounts, only those are returned
--   (discarding any zeroes).
--   
- Or if it contains any zero amounts (possibly more than one,
--   possibly in different commodities), all of those are returned.
--   
- Otherwise the null amount is returned.
--   
amountsPreservingZeros :: MixedAmount -> [Amount]

-- | Get a mixed amount's component amounts without normalising zero and
--   missing amounts. This is used for JSON serialisation, so the order is
--   important. In particular, we want the Amounts given in the order of
--   the MixedAmountKeys, i.e. lexicographically first by commodity, then
--   by price commodity, then by unit price from most negative to most
--   positive.
amountsRaw :: MixedAmount -> [Amount]

-- | Get this mixed amount's commodities as a set. Returns an empty set if
--   there are no amounts.
maCommodities :: MixedAmount -> Set CommoditySymbol

-- | Unify a MixedAmount to a single commodity value if possible. This
--   consolidates amounts of the same commodity and discards zero amounts;
--   but this one insists on simplifying to a single commodity, and will
--   return Nothing if this is not possible.
unifyMixedAmount :: MixedAmount -> Maybe Amount

-- | Filter a mixed amount's component amounts by a predicate.
filterMixedAmount :: (Amount -> Bool) -> MixedAmount -> MixedAmount

-- | Return an unnormalised MixedAmount containing exactly one Amount with
--   the specified commodity and the quantity of that commodity found in
--   the original. NB if Amount's quantity is zero it will be discarded
--   next time the MixedAmount gets normalised.
filterMixedAmountByCommodity :: CommoditySymbol -> MixedAmount -> MixedAmount

-- | Apply a transform to a mixed amount's component Amounts.
mapMixedAmount :: (Amount -> Amount) -> MixedAmount -> MixedAmount

-- | Convert all component amounts to cost/selling price where possible
--   (see amountCost).
mixedAmountCost :: MixedAmount -> MixedAmount
canonicaliseMixedAmount :: Map CommoditySymbol AmountStyle -> MixedAmount -> MixedAmount

-- | Given a map of standard commodity display styles, find and apply the
--   appropriate style to each individual amount.
styleMixedAmount :: Map CommoditySymbol AmountStyle -> MixedAmount -> MixedAmount
mixedAmountSetStyles :: Map CommoditySymbol AmountStyle -> MixedAmount -> MixedAmount

-- | Reset each individual amount's display style to the default.
mixedAmountUnstyled :: MixedAmount -> MixedAmount

-- | Get the string representation of a mixed amount, after normalising it
--   to one amount per commodity. Assumes amounts have no or similar
--   prices, otherwise this can show misleading prices.
--   
--   
--   showMixedAmount = wbUnpack . showMixedAmountB noColour
--   
showMixedAmount :: MixedAmount -> String

-- | Like showMixedAmount but uses the given amount display options. See
--   showMixedAmountB for special cases.
showMixedAmountWith :: AmountDisplayOpts -> MixedAmount -> String

-- | Get the one-line string representation of a mixed amount (also showing
--   any costs).
--   
--   
--   showMixedAmountOneLine = wbUnpack . showMixedAmountB oneLine
--   
showMixedAmountOneLine :: MixedAmount -> String

-- | Like showMixedAmount, but zero amounts are shown with their commodity
--   if they have one.
--   
--   
--   showMixedAmountWithZeroCommodity = wbUnpack . showMixedAmountB noColour{displayZeroCommodity=True}
--   
showMixedAmountWithZeroCommodity :: MixedAmount -> String

-- | Get the string representation of a mixed amount, without showing any
--   transaction prices. With a True argument, adds ANSI codes to show
--   negative amounts in red.
--   
--   
--   showMixedAmountWithoutPrice c = wbUnpack . showMixedAmountB noCost{displayColour=c}
--   
showMixedAmountWithoutPrice :: Bool -> MixedAmount -> String

-- | Get the one-line string representation of a mixed amount, but without
--   any @ prices. With a True argument, adds ANSI codes to show negative
--   amounts in red.
--   
--   
--   showMixedAmountOneLineWithoutPrice c = wbUnpack . showMixedAmountB oneLine{displayColour=c}
--   
showMixedAmountOneLineWithoutPrice :: Bool -> MixedAmount -> String

-- | Like showMixedAmountOneLineWithoutPrice, but show at most the given
--   width, with an elision indicator if there are more. With a True
--   argument, adds ANSI codes to show negative amounts in red.
--   
--   
--   showMixedAmountElided w c = wbUnpack . showMixedAmountB oneLine{displayColour=c, displayMaxWidth=Just w}
--   
showMixedAmountElided :: Int -> Bool -> MixedAmount -> String

-- | Get an unambiguous string representation of a mixed amount for
--   debugging.
showMixedAmountDebug :: MixedAmount -> String

-- | General function to generate a WideBuilder for a MixedAmount,
--   according to the supplied AmountDisplayOpts. This is the main function
--   to use for showing MixedAmounts, constructing a builder; it can then
--   be converted to a Text with wbToText, or to a String with wbUnpack.
--   
--   If a maximum width is given then: - If displayed on one line, it will
--   display as many Amounts as can fit in the given width, and further
--   Amounts will be elided. There will always be at least one amount
--   displayed, even if this will exceed the requested maximum width. - If
--   displayed on multiple lines, any Amounts longer than the maximum width
--   will be elided.
showMixedAmountB :: AmountDisplayOpts -> MixedAmount -> WideBuilder

-- | Helper for showMixedAmountB (and postingAsLines, ...) to show a list
--   of Amounts on multiple lines. This returns the list of WideBuilders:
--   one for each Amount, and padded/elided to the appropriate width. This
--   does not honour displayOneLine; all amounts will be displayed as if
--   displayOneLine were False.
showMixedAmountLinesB :: AmountDisplayOpts -> MixedAmount -> [WideBuilder]

-- | Set the display precision in the amount's commodities.
mixedAmountSetPrecision :: AmountPrecision -> MixedAmount -> MixedAmount

-- | In each component amount, increase the display precision sufficiently
--   to render it exactly (showing all significant decimal digits).
mixedAmountSetFullPrecision :: MixedAmount -> MixedAmount

-- | In each component amount, ensure the display precision is at least the
--   given value. Makes all amounts have an explicit Precision.
mixedAmountSetPrecisionMin :: Word8 -> MixedAmount -> MixedAmount

-- | In each component amount, ensure the display precision is at most the
--   given value. Makes all amounts have an explicit Precision.
mixedAmountSetPrecisionMax :: Word8 -> MixedAmount -> MixedAmount

-- | Remove all prices from a MixedAmount.
mixedAmountStripPrices :: MixedAmount -> MixedAmount
tests_Amount :: TestTree
valuationTypeValuationCommodity :: ValuationType -> Maybe CommoditySymbol

-- | Generate a price oracle (memoising price lookup function) from a
--   journal's directive-declared and transaction-inferred market prices.
--   For best performance, generate this only once per journal, reusing it
--   across reports if there are more than one, as compoundBalanceCommand
--   does. The boolean argument is whether to infer market prices from
--   transactions or not.
journalPriceOracle :: Bool -> Journal -> PriceOracle
priceDirectiveToMarketPrice :: PriceDirective -> MarketPrice

-- | Infer a market price from the given amount and its cost (if any), and
--   make a corresponding price directive on the given date. The price's
--   display precision will be set to show all significant decimal digits;
--   or if they seem to be infinite, defaultPrecisionLimit.
amountPriceDirectiveFromCost :: Day -> Amount -> Maybe PriceDirective

-- | Convert all component amounts to cost/selling price if requested, and
--   style them.
mixedAmountToCost :: Map CommoditySymbol AmountStyle -> ConversionOp -> MixedAmount -> MixedAmount

-- | Apply a specified valuation to this mixed amount, using the provided
--   price oracle, commodity styles, and reference dates. See
--   amountApplyValuation.
mixedAmountApplyValuation :: PriceOracle -> Map CommoditySymbol AmountStyle -> Day -> Day -> Day -> ValuationType -> MixedAmount -> MixedAmount

-- | Find the market value of each component amount in the given commodity,
--   or its default valuation commodity, at the given valuation date, using
--   the given market price oracle. When market prices available on that
--   date are not sufficient to calculate the value, amounts are left
--   unchanged.
mixedAmountValueAtDate :: PriceOracle -> Map CommoditySymbol AmountStyle -> Maybe CommoditySymbol -> Day -> MixedAmount -> MixedAmount

-- | Calculate the gain of each component amount, that is the difference
--   between the valued amount and the value of the cost basis (see
--   mixedAmountApplyValuation).
--   
--   If the commodity we are valuing in is not the same as the commodity of
--   the cost, this will value the cost at the same date as the primary
--   amount. This may not be what you want; for example you may want the
--   cost valued at the posting date. If so, let us know and we can change
--   this behaviour.
mixedAmountApplyGain :: PriceOracle -> Map CommoditySymbol AmountStyle -> Day -> Day -> Day -> ValuationType -> MixedAmount -> MixedAmount

-- | Calculate the gain of each component amount, that is the difference
--   between the valued amount and the value of the cost basis.
--   
--   If the commodity we are valuing in is not the same as the commodity of
--   the cost, this will value the cost at the same date as the primary
--   amount. This may not be what you want; for example you may want the
--   cost valued at the posting date. If so, let us know and we can change
--   this behaviour.
mixedAmountGainAtDate :: PriceOracle -> Map CommoditySymbol AmountStyle -> Maybe CommoditySymbol -> Day -> MixedAmount -> MixedAmount
marketPriceReverse :: MarketPrice -> MarketPrice
tests_Valuation :: TestTree

-- | Find and apply the appropriate display style to the posting amounts in
--   each commodity (see journalCommodityStyles). Main amount precisions
--   may be set or not according to the styles, but cost precisions are not
--   set.
postingApplyCommodityStyles :: Map CommoditySymbol AmountStyle -> Posting -> Posting

-- | Like postingApplyCommodityStyles, but neither main amount precisions
--   or cost precisions are set.
postingStyleAmounts :: Map CommoditySymbol AmountStyle -> Posting -> Posting
nullposting :: Posting
posting :: Posting

-- | Make a posting to an account.
post :: AccountName -> Amount -> Posting

-- | Make a virtual (unbalanced) posting to an account.
vpost :: AccountName -> Amount -> Posting

-- | Make a posting to an account, maybe with a balance assertion.
post' :: AccountName -> Amount -> Maybe BalanceAssertion -> Posting

-- | Make a virtual (unbalanced) posting to an account, maybe with a
--   balance assertion.
vpost' :: AccountName -> Amount -> Maybe BalanceAssertion -> Posting
nullsourcepos :: (SourcePos, SourcePos)
nullassertion :: BalanceAssertion

-- | Make a partial, exclusive balance assertion.
balassert :: Amount -> Maybe BalanceAssertion

-- | Make a total, exclusive balance assertion.
balassertTot :: Amount -> Maybe BalanceAssertion

-- | Make a partial, inclusive balance assertion.
balassertParInc :: Amount -> Maybe BalanceAssertion

-- | Make a total, inclusive balance assertion.
balassertTotInc :: Amount -> Maybe BalanceAssertion

-- | Render a balance assertion, as the =[=][*] symbol and expected amount.
showBalanceAssertion :: BalanceAssertion -> WideBuilder
originalPosting :: Posting -> Posting
showPosting :: Posting -> String

-- | Render a posting, at the appropriate width for aligning with its
--   siblings if any. Used by the rewrite command.
showPostingLines :: Posting -> [Text]

-- | Given a transaction and its postings, render the postings, suitable
--   for print output. Normally this output will be valid journal
--   syntax which hledger can reparse (though it may include
--   no-longer-valid balance assertions).
--   
--   Explicit amounts are shown, any implicit amounts are not.
--   
--   Postings with multicommodity explicit amounts are handled as follows:
--   if onelineamounts is true, these amounts are shown on one line,
--   comma-separated, and the output will not be valid journal syntax.
--   Otherwise, they are shown as several similar postings, one per
--   commodity. When the posting has a balance assertion, it is attached to
--   the last of these postings.
--   
--   The output will appear to be a balanced transaction. Amounts' display
--   precisions, which may have been limited by commodity directives, will
--   be increased if necessary to ensure this.
--   
--   Posting amounts will be aligned with each other, starting about 4
--   columns beyond the widest account name (see postingAsLines for
--   details).
postingsAsLines :: Bool -> [Posting] -> [Text]

-- | Render one posting, on one or more lines, suitable for print
--   output. There will be an indented account name, plus one or more of
--   status flag, posting amount, balance assertion, same-line comment,
--   next-line comments.
--   
--   If the posting's amount is implicit or if elideamount is true, no
--   amount is shown.
--   
--   If the posting's amount is explicit and multi-commodity, multiple
--   similar postings are shown, one for each commodity, to help produce
--   parseable journal syntax. Or if onelineamounts is true, such amounts
--   are shown on one line, comma-separated (and the output will not be
--   valid journal syntax).
--   
--   If an amount is zero, any commodity symbol attached to it is shown
--   (and the corresponding commodity display style is used).
--   
--   By default, 4 spaces (2 if there's a status flag) are shown between
--   account name and start of amount area, which is typically 12 chars
--   wide and contains a right-aligned amount (so 10-12 visible spaces
--   between account name and amount is typical). When given a list of
--   postings to be aligned with, the whitespace will be increased if
--   needed to match the posting with the longest account name. This is
--   used to align the amounts of a transaction's postings.
--   
--   Also returns the account width and amount width used.
postingAsLines :: Bool -> Bool -> Int -> Int -> Posting -> ([Text], Int, Int)

-- | Show an account name, clipped to the given width if any, and
--   appropriately bracketed/parenthesised for the given posting type.
showAccountName :: Maybe Int -> PostingType -> AccountName -> Text

-- | Like postingsAsLines but generates Beancount journal format.
postingsAsLinesBeancount :: [Posting] -> [Text]

-- | Like postingAsLines but generates Beancount journal format.
postingAsLinesBeancount :: Bool -> Int -> Int -> Posting -> ([Text], Int, Int)

-- | Like showAccountName for Beancount journal format. Calls
--   accountNameToBeancount first.
showAccountNameBeancount :: Maybe Int -> AccountName -> Text

-- | Render a transaction or posting's comment as indented,
--   semicolon-prefixed comment lines. The first line (unless empty) will
--   have leading space, subsequent lines will have a larger indent.
renderCommentLines :: Text -> [Text]
isReal :: Posting -> Bool
isVirtual :: Posting -> Bool
isBalancedVirtual :: Posting -> Bool
hasAmount :: Posting -> Bool
hasBalanceAssignment :: Posting -> Bool

-- | Sorted unique account names referenced by these postings.
accountNamesFromPostings :: [Posting] -> [AccountName]

-- | Sum all amounts from a list of postings.
sumPostings :: [Posting] -> MixedAmount

-- | Strip all prices from a Posting.
postingStripPrices :: Posting -> Posting

-- | Get a posting's (primary) date - it's own primary date if specified,
--   otherwise the parent transaction's primary date, or the null date if
--   there is no parent transaction.
postingDate :: Posting -> Day

-- | Get a posting's secondary (secondary) date, which is the first of:
--   posting's secondary date, transaction's secondary date, posting's
--   primary date, transaction's primary date, or the null date if there is
--   no parent transaction.
postingDate2 :: Posting -> Day

-- | Get a posting's primary or secondary date, as specified.
postingDateOrDate2 :: WhichDate -> Posting -> Day

-- | Get a posting's status. This is cleared or pending if those are
--   explicitly set on the posting, otherwise the status of its parent
--   transaction, or unmarked if there is no parent transaction. (Note the
--   ambiguity, unmarked can mean "posting and transaction are both
--   unmarked" or "posting is unmarked and don't know about the
--   transaction".
postingStatus :: Posting -> Status

-- | Tags for this posting including any inherited from its parent
--   transaction.
postingAllTags :: Posting -> [Tag]

-- | Tags for this transaction including any from its postings.
transactionAllTags :: Transaction -> [Tag]
relatedPostings :: Posting -> [Posting]

-- | Does this posting fall within the given date span ?
isPostingInDateSpan :: DateSpan -> Posting -> Bool
isPostingInDateSpan' :: WhichDate -> DateSpan -> Posting -> Bool
isEmptyPosting :: Posting -> Bool

-- | Apply some account aliases to the posting's account name, as described
--   by accountNameApplyAliases. This can fail due to a bad replacement
--   pattern in a regular expression alias.
postingApplyAliases :: [AccountAlias] -> Posting -> Either RegexError Posting

-- | Add tags to a posting, discarding any for which the posting already
--   has a value.
postingAddTags :: Posting -> [Tag] -> Posting

-- | Apply a specified valuation to this posting's amount, using the
--   provided price oracle, commodity styles, and reference dates. See
--   amountApplyValuation.
postingApplyValuation :: PriceOracle -> Map CommoditySymbol AmountStyle -> Day -> Day -> ValuationType -> Posting -> Posting

-- | Maybe convert this Postings amount to cost.
postingToCost :: ConversionOp -> Posting -> Maybe Posting

-- | Generate inferred equity postings from a Posting using
--   transaction prices. Make sure not to generate equity postings when
--   there are already matched conversion postings.
postingAddInferredEquityPostings :: Bool -> Text -> Posting -> [Posting]

-- | Make a market price equivalent to this posting's amount's unit price,
--   if any.
postingPriceDirectivesFromCost :: Posting -> [PriceDirective]

-- | Apply a transform function to this posting's amount.
postingTransformAmount :: (MixedAmount -> MixedAmount) -> Posting -> Posting

-- | Join two parts of a comment, eg a tag and another tag, or a tag and a
--   non-tag, on a single line. Interpolates a comma and space unless one
--   of the parts is empty.
commentJoin :: Text -> Text -> Text

-- | Add a tag to a comment, comma-separated from any prior content. A
--   space is inserted following the colon, before the value.
commentAddTag :: Text -> Tag -> Text

-- | Like commentAddTag, but omits the space after the colon.
commentAddTagUnspaced :: Text -> Tag -> Text

-- | Add a tag on its own line to a comment, preserving any prior content.
--   A space is inserted following the colon, before the value.
commentAddTagNextLine :: Text -> Tag -> Text
tests_Posting :: TestTree
nulltransaction :: Transaction

-- | Make a simple transaction with the given date and postings.
transaction :: Day -> [Posting] -> Transaction
transactionPayee :: Transaction -> Text
transactionNote :: Transaction -> Text

-- | Render a journal transaction as text similar to the style of Ledger's
--   print command.
--   
--   Adapted from Ledger 2.x and 3.x standard format:
--   
--   
--   yyyy-mm-dd[ *][ CODE] description.........          [  ; comment...............]
--       account name 1.....................  ...$amount1[  ; comment...............]
--       account name 2.....................  ..$-amount1[  ; comment...............]
--   
--   pcodewidth    = no limit -- 10          -- mimicking ledger layout.
--   pdescwidth    = no limit -- 20          -- I don't remember what these mean,
--   pacctwidth    = 35 minimum, no maximum  -- they were important at the time.
--   pamtwidth     = 11
--   pcommentwidth = no limit -- 22
--   
--   
--   The output will be parseable journal syntax. To facilitate this,
--   postings with explicit multi-commodity amounts are displayed as
--   multiple similar postings, one per commodity. (Normally does not
--   happen with this function).
showTransaction :: Transaction -> Text

-- | Like showTransaction, but explicit multi-commodity amounts are shown
--   on one line, comma-separated. In this case the output will not be
--   parseable journal syntax.
showTransactionOneLineAmounts :: Transaction -> Text
showTransactionLineFirstPart :: Transaction -> Text

-- | Like showTransaction, but generates Beancount journal format.
showTransactionBeancount :: Transaction -> Text
hasRealPostings :: Transaction -> Bool
realPostings :: Transaction -> [Posting]
assignmentPostings :: Transaction -> [Posting]
virtualPostings :: Transaction -> [Posting]
balancedVirtualPostings :: Transaction -> [Posting]
transactionsPostings :: [Transaction] -> [Posting]
transactionDate2 :: Transaction -> Day
transactionDateOrDate2 :: WhichDate -> Transaction -> Day

-- | Ensure a transaction's postings refer back to it, so that eg
--   relatedPostings works right.
txnTieKnot :: Transaction -> Transaction

-- | Ensure a transaction's postings do not refer back to it, so that eg
--   recursiveSize and GHCI's :sprint work right.
txnUntieKnot :: Transaction -> Transaction

-- | Apply a transform function to this transaction's amounts.
transactionTransformPostings :: (Posting -> Posting) -> Transaction -> Transaction

-- | Apply a specified valuation to this transaction's amounts, using the
--   provided price oracle, commodity styles, and reference dates. See
--   amountApplyValuation.
transactionApplyValuation :: PriceOracle -> Map CommoditySymbol AmountStyle -> Day -> Day -> ValuationType -> Transaction -> Transaction

-- | Maybe convert this Transactions amounts to cost.
transactionToCost :: ConversionOp -> Transaction -> Transaction

-- | Add inferred equity postings to a Transaction using transaction
--   prices.
transactionAddInferredEquityPostings :: Bool -> AccountName -> Transaction -> Transaction

-- | Add costs inferred from equity postings in this transaction. The
--   name(s) of conversion equity accounts should be provided. For every
--   adjacent pair of conversion postings, it will first search the
--   postings with costs to see if any match. If so, it will tag these as
--   matched. If no postings with costs match, it will then search the
--   postings without costs, and will match the first such posting which
--   matches one of the conversion amounts. If it finds a match, it will
--   add a cost and then tag it. If the first argument is true, do a dry
--   run instead: identify and tag the costful and conversion postings, but
--   don't add costs.
transactionInferCostsFromEquity :: Bool -> [AccountName] -> Transaction -> Either String Transaction
partitionAndCheckConversionPostings :: Bool -> [AccountName] -> [IdxPosting] -> Either Text ([(IdxPosting, IdxPosting)], ([IdxPosting], [IdxPosting]))

-- | Apply some account aliases to all posting account names in the
--   transaction, as described by accountNameApplyAliases. This can fail
--   due to a bad replacement pattern in a regular expression alias.
transactionApplyAliases :: [AccountAlias] -> Transaction -> Either RegexError Transaction

-- | Apply a transformation to a transaction's postings.
transactionMapPostings :: (Posting -> Posting) -> Transaction -> Transaction

-- | Apply a transformation to a transaction's posting amounts.
transactionMapPostingAmounts :: (MixedAmount -> MixedAmount) -> Transaction -> Transaction

-- | All posting amounts from this transactin, in order.
transactionAmounts :: Transaction -> [MixedAmount]

-- | The file path from which this transaction was parsed.
transactionFile :: Transaction -> FilePath
annotateErrorWithTransaction :: Transaction -> String -> String
tests_Transaction :: TestTree

-- | Construct a payee tag
payeeTag :: Maybe Text -> Either RegexError Query

-- | Construct a note tag
noteTag :: Maybe Text -> Either RegexError Query

-- | Construct a generated-transaction tag
generatedTransactionTag :: Query

-- | A version of parseQueryList which acts on a single Text of
--   space-separated terms.
--   
--   The usual shell quoting rules are assumed. When a pattern contains
--   whitespace, it (or the whole term including prefix) should be enclosed
--   in single or double quotes.
--   
--   A query term is either:
--   
--   
--   
- a search pattern, which matches on one or more fields,
--   eg:acct:REGEXP - match the account name with a regular expression
--   desc:REGEXP - match the transaction description date:PERIODEXP - match
--   the date with a period expression
--   
--   
--   The prefix indicates the field to match, or if there is no prefix
--   account name is assumed.
--   
--   
--   
- a query option, which modifies the reporting behaviour in some
--   way. There is currently one of these, which may appear only
--   once:inacct:FULLACCTNAME
--   
--   
--   Period expressions may contain relative dates, so a reference date is
--   required to fully parse these.
--   
--   
--   >>> parseQuery nulldate "expenses:dining out"
--   Right (Or [Acct (RegexpCI "expenses:dining"),Acct (RegexpCI "out")],[])
--   
--   
--   
--   >>> parseQuery nulldate "\"expenses:dining out\""
--   Right (Acct (RegexpCI "expenses:dining out"),[])
--   
parseQuery :: Day -> Text -> Either String (Query, [QueryOpt])

-- | Convert a list of space-separated queries to a single query
--   
--   Multiple terms are combined as follows: 1. multiple account patterns
--   are OR'd together 2. multiple description patterns are OR'd together
--   3. multiple status patterns are OR'd together 4. then all terms are
--   AND'd together
parseQueryList :: Day -> [Text] -> Either String (Query, [QueryOpt])

-- | Quote-and-prefix-aware version of words - don't split on spaces which
--   are inside quotes, including quotes which may have one of the
--   specified prefixes in front, and maybe an additional not: prefix in
--   front of that.
words'' :: [Text] -> Text -> [Text]
queryprefixes :: [Text]

-- | Parse a single query term as either a query or a query option, or
--   return an error message if parsing fails.
parseQueryTerm :: Day -> Text -> Either String (Query, [QueryOpt])

-- | Case-insensitively parse one single-letter code, or one long-form word
--   if permitted, to an account type. On failure, returns the unparseable
--   text.
parseAccountType :: Bool -> Text -> Either String AccountType
simplifyQuery :: Query -> Query

-- | Remove query terms (or whole sub-expressions) from this query which do
--   not match the given predicate. XXX Semantics not completely clear.
--   Also calls simplifyQuery on the result.
filterQuery :: (Query -> Bool) -> Query -> Query

-- | Remove query terms (or whole sub-expressions) from this query which
--   match neither the given predicate nor that predicate negated (eg, if
--   predicate is queryIsAcct, this will keep both "acct:" and "not:acct:"
--   terms). Also calls simplifyQuery on the result. (Since 1.24.1, might
--   be merged into filterQuery in future.) XXX Semantics not completely
--   clear.
filterQueryOrNotQuery :: (Query -> Bool) -> Query -> Query

-- | Does this simple query predicate match any part of this possibly
--   compound query ?
matchesQuery :: (Query -> Bool) -> Query -> Bool

-- | Does this query match everything ?
queryIsNull :: Query -> Bool

-- | Is this a simple query of this type (date:) ? Does not match a
--   compound query involving andornot. Likewise for the following
--   functions.
queryIsDate :: Query -> Bool
queryIsDate2 :: Query -> Bool
queryIsDateOrDate2 :: Query -> Bool
queryIsStatus :: Query -> Bool
queryIsCode :: Query -> Bool
queryIsDesc :: Query -> Bool
queryIsTag :: Query -> Bool
queryIsAcct :: Query -> Bool
queryIsType :: Query -> Bool
queryIsDepth :: Query -> Bool
queryIsReal :: Query -> Bool
queryIsAmt :: Query -> Bool
queryIsSym :: Query -> Bool

-- | Does this query specify a start date and nothing else (that would
--   filter postings prior to the date) ? When the flag is true, look for a
--   starting secondary date instead.
queryIsStartDateOnly :: Bool -> Query -> Bool

-- | Does this query involve a property of transactions (or their
--   postings), making it inapplicable to account declarations ?
queryIsTransactionRelated :: Query -> Bool

-- | What start date (or secondary date) does this query specify, if any ?
--   For OR expressions, use the earliest of the dates. NOT is ignored.
queryStartDate :: Bool -> Query -> Maybe Day

-- | What end date (or secondary date) does this query specify, if any ?
--   For OR expressions, use the latest of the dates. NOT is ignored.
queryEndDate :: Bool -> Query -> Maybe Day

-- | What date span (or with a true argument, what secondary date span)
--   does this query specify ? OR clauses specifying multiple spans return
--   their union (the span enclosing all of them). AND clauses specifying
--   multiple spans return their intersection. NOT clauses are ignored.
queryDateSpan :: Bool -> Query -> DateSpan

-- | What date span does this query specify, treating primary and secondary
--   dates as equivalent ? OR clauses specifying multiple spans return
--   their union (the span enclosing all of them). AND clauses specifying
--   multiple spans return their intersection. NOT clauses are ignored.
queryDateSpan' :: Query -> DateSpan

-- | The depth limit this query specifies, if it has one
queryDepth :: Query -> Maybe Int

-- | The account we are currently focussed on, if any, and whether
--   subaccounts are included. Just looks at the first query option.
inAccount :: [QueryOpt] -> Maybe (AccountName, Bool)

-- | A query for the account(s) we are currently focussed on, if any. Just
--   looks at the first query option.
inAccountQuery :: [QueryOpt] -> Maybe Query
matchesCommodity :: Query -> CommoditySymbol -> Bool

-- | Does the match expression match this (simple) amount ?
matchesAmount :: Query -> Amount -> Bool
matchesMixedAmount :: Query -> MixedAmount -> Bool

-- | Does the query match this account name ? A matching in: clause is also
--   considered a match.
matchesAccount :: Query -> AccountName -> Bool

-- | Like matchesAccount, but with optional extra matching features:
--   
--   
--   
- If the account's type is provided, any type: terms in the query
--   must match it (and any negated type: terms must not match it).
--   
- If the account's tags are provided, any tag: terms must match at
--   least one of them (and any negated tag: terms must match none).
--   
matchesAccountExtra :: (AccountName -> Maybe AccountType) -> (AccountName -> [Tag]) -> Query -> AccountName -> Bool

-- | Does the match expression match this posting ? When matching account
--   name, and the posting has been transformed in some way, we will match
--   either the original or transformed name.
matchesPosting :: Query -> Posting -> Bool

-- | Like matchesPosting, but if the posting's account's type is provided,
--   any type: terms in the query must match it (and any negated type:
--   terms must not match it).
matchesPostingExtra :: (AccountName -> Maybe AccountType) -> Query -> Posting -> Bool

-- | Does the match expression match this transaction ?
matchesTransaction :: Query -> Transaction -> Bool

-- | Like matchesTransaction, but if the journal's account types are
--   provided, any type: terms in the query must match at least one
--   posting's account type (and any negated type: terms must match none).
matchesTransactionExtra :: (AccountName -> Maybe AccountType) -> Query -> Transaction -> Bool

-- | Does the query match this transaction description ? Tests desc: terms,
--   any other terms are ignored.
matchesDescription :: Query -> Text -> Bool

-- | Does the query match this transaction payee ? Tests desc: (and payee:
--   ?) terms, any other terms are ignored. XXX Currently an alias for
--   matchDescription. I'm not sure if more is needed, There's some
--   shenanigan with payee: and "payeeTag" to figure out.
matchesPayeeWIP :: Query -> Payee -> Bool

-- | Does the query match the name and optionally the value of any of these
--   tags ?
matchesTags :: Regexp -> Maybe Regexp -> [Tag] -> Bool

-- | Does the query match this market price ?
matchesPriceDirective :: Query -> PriceDirective -> Bool
tests_Query :: TestTree

-- | Apply all the given transaction modifiers, in turn, to each
--   transaction. Or if any of them fails to be parsed, return the first
--   error. A reference date is provided to help interpret relative dates
--   in transaction modifier queries.
modifyTransactions :: (AccountName -> Maybe AccountType) -> (AccountName -> [Tag]) -> Map CommoditySymbol AmountStyle -> Day -> Bool -> [TransactionModifier] -> [Transaction] -> Either String [Transaction]

-- | Convert time log entries to journal transactions. When there is no
--   clockout, add one with the provided current time. Sessions crossing
--   midnight are split into days to give accurate per-day totals.
timeclockEntriesToTransactions :: LocalTime -> [TimeclockEntry] -> [Transaction]
tests_Timeclock :: TestTree

-- | Given an account name and its account directive, and a problem tag
--   within the latter: render it as a megaparsec-style excerpt, showing
--   the original line number and marked column or region. Returns the file
--   path, line number, column(s) if known, and the rendered excerpt, or as
--   much of these as is possible. The returned columns will be accurate
--   for the rendered error message but not for the original journal data.
makeAccountTagErrorExcerpt :: (AccountName, AccountDeclarationInfo) -> TagName -> (FilePath, Int, Maybe (Int, Maybe Int), Text)

-- | Given a problem transaction and a function calculating the best
--   column(s) for marking the error region: render it as a
--   megaparsec-style excerpt, showing the original line number on the
--   transaction line, and a column(s) marker. Returns the file path, line
--   number, column(s) if known, and the rendered excerpt, or as much of
--   these as is possible. The returned columns will be accurate for the
--   rendered error message but not for the original journal data.
makeTransactionErrorExcerpt :: Transaction -> (Transaction -> Maybe (Int, Maybe Int)) -> (FilePath, Int, Maybe (Int, Maybe Int), Text)

-- | Given a problem posting and a function calculating the best column(s)
--   for marking the error region: look up error info from the parent
--   transaction, and render the transaction as a megaparsec-style excerpt,
--   showing the original line number on the problem posting's line, and a
--   column indicator. Returns the file path, line number, column(s) if
--   known, and the rendered excerpt, or as much of these as is possible. A
--   limitation: columns will be accurate for the rendered error message
--   but not for the original journal data.
makePostingErrorExcerpt :: Posting -> (Posting -> Transaction -> Text -> Maybe (Int, Maybe Int)) -> (FilePath, Int, Maybe (Int, Maybe Int), Text)

-- | Find the 1-based index of the first posting in this transaction
--   satisfying the given predicate.
transactionFindPostingIndex :: (Posting -> Bool) -> Transaction -> Maybe Int

-- | From the given posting, make an error excerpt showing the transaction
--   with this posting's account part highlighted.
makePostingAccountErrorExcerpt :: Posting -> (FilePath, Int, Maybe (Int, Maybe Int), Text)

-- | From the given posting, make an error excerpt showing the transaction
--   with the balance assertion highlighted.
makeBalanceAssertionErrorExcerpt :: Posting -> (FilePath, Int, Maybe (Int, Maybe Int), Text)
journalCheckOrdereddates :: WhichDate -> Journal -> Either String ()

-- | Generate transactions from PeriodicTransaction within a
--   DateSpan. This should be a closed span with both start and end
--   dates specified; an open ended span will generate no transactions.
--   
--   Note that new transactions require txnTieKnot post-processing.
--   The new transactions will have three tags added: - a
--   recur:PERIODICEXPR tag whose value is the generating periodic
--   expression - a generated-transaction: tag - a hidden
--   _generated-transaction: tag which does not appear in the comment.
--   
--   
--   >>> import Data.Time (fromGregorian)
--   
--   >>> _ptgen "monthly from 2017/1 to 2017/4"
--   2017-01-01
--       ; generated-transaction: ~ monthly from 2017/1 to 2017/4
--       a           $1.00
--   
--   2017-02-01
--       ; generated-transaction: ~ monthly from 2017/1 to 2017/4
--       a           $1.00
--   
--   2017-03-01
--       ; generated-transaction: ~ monthly from 2017/1 to 2017/4
--       a           $1.00
--   
--   
--   
--   >>> _ptgen "monthly from 2017/1 to 2017/5"
--   2017-01-01
--       ; generated-transaction: ~ monthly from 2017/1 to 2017/5
--       a           $1.00
--   
--   2017-02-01
--       ; generated-transaction: ~ monthly from 2017/1 to 2017/5
--       a           $1.00
--   
--   2017-03-01
--       ; generated-transaction: ~ monthly from 2017/1 to 2017/5
--       a           $1.00
--   
--   2017-04-01
--       ; generated-transaction: ~ monthly from 2017/1 to 2017/5
--       a           $1.00
--   
--   
--   
--   >>> _ptgen "every 2nd day of month from 2017/02 to 2017/04"
--   2017-01-02
--       ; generated-transaction: ~ every 2nd day of month from 2017/02 to 2017/04
--       a           $1.00
--   
--   2017-02-02
--       ; generated-transaction: ~ every 2nd day of month from 2017/02 to 2017/04
--       a           $1.00
--   
--   2017-03-02
--       ; generated-transaction: ~ every 2nd day of month from 2017/02 to 2017/04
--       a           $1.00
--   
--   
--   
--   >>> _ptgen "every 30th day of month from 2017/1 to 2017/5"
--   2016-12-30
--       ; generated-transaction: ~ every 30th day of month from 2017/1 to 2017/5
--       a           $1.00
--   
--   2017-01-30
--       ; generated-transaction: ~ every 30th day of month from 2017/1 to 2017/5
--       a           $1.00
--   
--   2017-02-28
--       ; generated-transaction: ~ every 30th day of month from 2017/1 to 2017/5
--       a           $1.00
--   
--   2017-03-30
--       ; generated-transaction: ~ every 30th day of month from 2017/1 to 2017/5
--       a           $1.00
--   
--   2017-04-30
--       ; generated-transaction: ~ every 30th day of month from 2017/1 to 2017/5
--       a           $1.00
--   
--   
--   
--   >>> _ptgen "every 2nd Thursday of month from 2017/1 to 2017/4"
--   2016-12-08
--       ; generated-transaction: ~ every 2nd Thursday of month from 2017/1 to 2017/4
--       a           $1.00
--   
--   2017-01-12
--       ; generated-transaction: ~ every 2nd Thursday of month from 2017/1 to 2017/4
--       a           $1.00
--   
--   2017-02-09
--       ; generated-transaction: ~ every 2nd Thursday of month from 2017/1 to 2017/4
--       a           $1.00
--   
--   2017-03-09
--       ; generated-transaction: ~ every 2nd Thursday of month from 2017/1 to 2017/4
--       a           $1.00
--   
--   
--   
--   >>> _ptgen "every nov 29th from 2017 to 2019"
--   2016-11-29
--       ; generated-transaction: ~ every nov 29th from 2017 to 2019
--       a           $1.00
--   
--   2017-11-29
--       ; generated-transaction: ~ every nov 29th from 2017 to 2019
--       a           $1.00
--   
--   2018-11-29
--       ; generated-transaction: ~ every nov 29th from 2017 to 2019
--       a           $1.00
--   
--   
--   
--   >>> _ptgen "2017/1"
--   2017-01-01
--       ; generated-transaction: ~ 2017/1
--       a           $1.00
--   
--   
--   
--   >>> let reportperiod="daily from 2018/01/03" in let (i,s) = parsePeriodExpr' nulldate reportperiod in runPeriodicTransaction True (nullperiodictransaction{ptperiodexpr=reportperiod, ptspan=s, ptinterval=i, ptpostings=["a" `post` usd 1]}) (DateSpan (Just $ Flex $ fromGregorian 2018 01 01) (Just $ Flex $ fromGregorian 2018 01 03))
--   []
--   
--   
--   
--   >>> _ptgenspan "every 3 months from 2019-05" (DateSpan (Just $ Flex $ fromGregorian 2020 01 01) (Just $ Flex $ fromGregorian 2020 02 01))
--   
--   
--   
--   >>> _ptgenspan "every 3 months from 2019-05" (DateSpan (Just $ Flex $ fromGregorian 2020 02 01) (Just $ Flex $ fromGregorian 2020 03 01))
--   2020-02-01
--       ; generated-transaction: ~ every 3 months from 2019-05
--       a           $1.00
--   
--   
--   >>> _ptgenspan "every 3 days from 2018" (DateSpan (Just $ Flex $ fromGregorian 2018 01 01) (Just $ Flex $ fromGregorian 2018 01 05))
--   2018-01-01
--       ; generated-transaction: ~ every 3 days from 2018
--       a           $1.00
--   
--   2018-01-04
--       ; generated-transaction: ~ every 3 days from 2018
--       a           $1.00
--   
--   
--   >>> _ptgenspan "every 3 days from 2018" (DateSpan (Just $ Flex $ fromGregorian 2018 01 02) (Just $ Flex $ fromGregorian 2018 01 05))
--   2018-01-04
--       ; generated-transaction: ~ every 3 days from 2018
--       a           $1.00
--   
runPeriodicTransaction :: Bool -> PeriodicTransaction -> DateSpan -> [Transaction]

-- | Check that this date span begins at a boundary of this interval, or
--   return an explanatory error message including the provided period
--   expression (from which the span and interval are derived).
checkPeriodicTransactionStartDate :: Interval -> DateSpan -> Text -> Maybe String

-- | Show a JSON-convertible haskell value as pretty-printed JSON text.
toJsonText :: ToJSON a => a -> Text

-- | Write a JSON-convertible haskell value to a pretty-printed JSON file.
--   Eg: writeJsonFile "a.json" nulltransaction
writeJsonFile :: ToJSON a => FilePath -> a -> IO ()

-- | Read a JSON file and decode it to the target type, or raise an error
--   if we can't. Eg: readJsonFile "a.json" :: IO Transaction
readJsonFile :: FromJSON a => FilePath -> IO a

-- | Merge two journals into one. Transaction counts are summed, map fields
--   are combined, the second's list fields are appended to the first's,
--   the second's parse state is kept.
journalConcat :: Journal -> Journal -> Journal

-- | Renumber all the account declarations. This is useful to call when
--   finalising or concatenating Journals, to give account declarations a
--   total order across files.
journalRenumberAccountDeclarations :: Journal -> Journal

-- | Debug log the ordering of a journal's account declarations (at debug
--   level 5+).
dbgJournalAcctDeclOrder :: String -> Journal -> Journal
nulljournal :: Journal
journalFilePath :: Journal -> FilePath
journalFilePaths :: Journal -> [FilePath]
addTransaction :: Transaction -> Journal -> Journal
addTransactionModifier :: TransactionModifier -> Journal -> Journal
addPeriodicTransaction :: PeriodicTransaction -> Journal -> Journal
addPriceDirective :: PriceDirective -> Journal -> Journal

-- | Get the transaction with this index (its 1-based position in the input
--   stream), if any.
journalTransactionAt :: Journal -> Integer -> Maybe Transaction

-- | Get the transaction that appeared immediately after this one in the
--   input stream, if any.
journalNextTransaction :: Journal -> Transaction -> Maybe Transaction

-- | Get the transaction that appeared immediately before this one in the
--   input stream, if any.
journalPrevTransaction :: Journal -> Transaction -> Maybe Transaction

-- | All postings from this journal's transactions, in order.
journalPostings :: Journal -> [Posting]

-- | All posting amounts from this journal, in order.
journalPostingAmounts :: Journal -> [MixedAmount]

-- | Show the journal amounts rendered, suitable for debug logging.
showJournalAmountsDebug :: Journal -> String

-- | Sorted unique commodity symbols declared by commodity directives in
--   this journal.
journalCommoditiesDeclared :: Journal -> [CommoditySymbol]

-- | Sorted unique commodity symbols declared or inferred from this
--   journal.
journalCommodities :: Journal -> Set CommoditySymbol

-- | Unique transaction descriptions used in this journal.
journalDescriptions :: Journal -> [Text]

-- | Sorted unique payees declared by payee directives in this journal.
journalPayeesDeclared :: Journal -> [Payee]

-- | Sorted unique payees used by transactions in this journal.
journalPayeesUsed :: Journal -> [Payee]

-- | Sorted unique payees used in transactions or declared by payee
--   directives in this journal.
journalPayeesDeclaredOrUsed :: Journal -> [Payee]

-- | Sorted unique tag names declared by tag directives in this journal.
journalTagsDeclared :: Journal -> [TagName]

-- | Sorted unique tag names used in this journal (in account directives,
--   transactions, postings..)
journalTagsUsed :: Journal -> [TagName]

-- | Sorted unique tag names used in transactions or declared by tag
--   directives in this journal.
journalTagsDeclaredOrUsed :: Journal -> [TagName]

-- | Sorted unique account names posted to by this journal's transactions.
journalAccountNamesUsed :: Journal -> [AccountName]

-- | Sorted unique account names implied by this journal's transactions -
--   accounts posted to and all their implied parent accounts.
journalAccountNamesImplied :: Journal -> [AccountName]

-- | Sorted unique account names declared by account directives in this
--   journal.
journalAccountNamesDeclared :: Journal -> [AccountName]

-- | Sorted unique account names declared by account directives in this
--   journal, which have no children.
journalLeafAccountNamesDeclared :: Journal -> [AccountName]

-- | Sorted unique account names declared by account directives or posted
--   to by transactions in this journal.
journalAccountNamesDeclaredOrUsed :: Journal -> [AccountName]

-- | Sorted unique account names declared by account directives, or posted
--   to or implied as parents by transactions in this journal.
journalAccountNamesDeclaredOrImplied :: Journal -> [AccountName]

-- | Convenience/compatibility alias for
--   journalAccountNamesDeclaredOrImplied.
journalAccountNames :: Journal -> [AccountName]

-- | Sorted unique account names declared or implied in this journal which
--   have no children.
journalLeafAccountNames :: Journal -> [AccountName]
journalAccountNameTree :: Journal -> Tree AccountName

-- | Which tags have been declared explicitly for this account, if any ?
journalAccountTags :: Journal -> AccountName -> [Tag]

-- | Which tags are in effect for this account, including tags inherited
--   from parent accounts ?
journalInheritedAccountTags :: Journal -> AccountName -> [Tag]

-- | Find up to N most similar and most recent transactions matching the
--   given transaction description and query and exceeding the given
--   description similarity score (0 to 1, see compareDescriptions).
--   Returns transactions along with their age in days compared to the
--   latest transaction date, their description similarity score, and a
--   heuristically date-weighted variant of this that favours more recent
--   transactions.
journalTransactionsSimilarTo :: Journal -> Text -> Query -> SimilarityScore -> Int -> [(DateWeightedSimilarityScore, Age, SimilarityScore, Transaction)]
journalAccountType :: Journal -> AccountName -> Maybe AccountType

-- | Add a map of all known account types to the journal.
journalAddAccountTypes :: Journal -> Journal

-- | Build a map of all known account types, explicitly declared or
--   inferred from the account's parent or name.
journalAccountTypes :: Journal -> Map AccountName AccountType

-- | To all postings in the journal, add any tags from their account
--   (including those inherited from parent accounts). If the same tag
--   exists on posting and account, the latter is ignored.
journalPostingsAddAccountTags :: Journal -> Journal

-- | The account to use for automatically generated conversion postings in
--   this journal: the first of the journalConversionAccounts.
journalConversionAccount :: Journal -> AccountName

-- | All the accounts declared or inferred as Conversion type in this
--   journal.
journalConversionAccounts :: Journal -> [AccountName]

-- | Keep only transactions matching the query expression.
filterJournalTransactions :: Query -> Journal -> Journal

-- | Keep only postings matching the query expression. This can leave
--   unbalanced transactions.
filterJournalPostings :: Query -> Journal -> Journal

-- | Keep only postings which do not match the query expression, but for
--   which a related posting does. This can leave unbalanced transactions.
filterJournalRelatedPostings :: Query -> Journal -> Journal

-- | Within each posting's amount, keep only the parts matching the query,
--   and remove any postings with all amounts removed. This can leave
--   unbalanced transactions.
filterJournalAmounts :: Query -> Journal -> Journal

-- | Filter out all parts of this transaction's amounts which do not match
--   the query, and remove any postings with all amounts removed. This can
--   leave the transaction unbalanced.
filterTransactionAmounts :: Query -> Transaction -> Transaction

-- | Filter out all parts of this posting's amount which do not match the
--   query, and remove the posting if this removes all amounts.
filterPostingAmount :: Query -> Posting -> Maybe Posting
filterTransactionPostings :: Query -> Transaction -> Transaction
filterTransactionPostingsExtra :: (AccountName -> Maybe AccountType) -> Query -> Transaction -> Transaction
filterTransactionRelatedPostings :: Query -> Transaction -> Transaction

-- | Apply a transformation to a journal's transactions.
journalMapTransactions :: (Transaction -> Transaction) -> Journal -> Journal

-- | Apply a transformation to a journal's postings.
journalMapPostings :: (Posting -> Posting) -> Journal -> Journal

-- | Apply a transformation to a journal's posting amounts.
journalMapPostingAmounts :: (MixedAmount -> MixedAmount) -> Journal -> Journal

-- | Reverse all lists of parsed items, which during parsing were prepended
--   to, so that the items are in parse order. Part of post-parse
--   finalisation.
journalReverse :: Journal -> Journal

-- | Set this journal's last read time, ie when its files were last read.
journalSetLastReadTime :: POSIXTime -> Journal -> Journal
journalNumberAndTieTransactions :: Journal -> Journal

-- | Number (set the tindex field) this journal's transactions, counting
--   upward from 1.
journalNumberTransactions :: Journal -> Journal

-- | Untie all transaction-posting knots in this journal, so that eg
--   recursiveSize and GHCI's :sprint can work on it.
journalUntieTransactions :: Transaction -> Transaction

-- | Apply any transaction modifier rules in the journal (adding automated
--   postings to transactions, eg). Or if a modifier rule fails to parse,
--   return the error message. A reference date is provided to help
--   interpret relative dates in transaction modifier queries. The first
--   argument selects whether to add visible tags to generated postings
--   & modified transactions.
journalModifyTransactions :: Bool -> Day -> Journal -> Either String Journal

-- | Apply this journal's commodity display styles to all of its amounts.
--   This does no display rounding, keeping decimal digits as they were; it
--   is suitable for an early cleanup pass before calculations. Reports may
--   want to do additional rounding/styling at render time. This can return
--   an error message eg if inconsistent number formats are found.
journalStyleAmounts :: Journal -> Either String Journal

-- | Get the canonical amount styles for this journal, whether (in order of
--   precedence): set globally in InputOpts, declared by commodity
--   directives, declared by a default commodity (D) directive, or inferred
--   from posting amounts, as a map from symbol to style. Styles from
--   directives are assumed to specify the decimal mark.
journalCommodityStyles :: Journal -> Map CommoditySymbol AmountStyle

-- | Like journalCommodityStyles, but attach a particular rounding strategy
--   to the styles, affecting how they will affect display precisions when
--   applied.
journalCommodityStylesWith :: Rounding -> Journal -> Map CommoditySymbol AmountStyle

-- | Collect and save inferred amount styles for each commodity based on
--   the posting amounts in that commodity (excluding price amounts), ie:
--   "the format of the first amount, adjusted to the highest precision of
--   all amounts". Can return an error message eg if inconsistent number
--   formats are found.
journalInferCommodityStyles :: Journal -> Either String Journal

-- | Given a list of amounts, in parse order (roughly speaking; see
--   journalStyleInfluencingAmounts), build a map from their commodity
--   names to standard commodity display formats. Can return an error
--   message eg if inconsistent number formats are found.
--   
--   Though, these amounts may have come from multiple files, so we
--   shouldn't assume they use consistent number formats. Currently we
--   don't enforce that even within a single file, and this function never
--   reports an error.
commodityStylesFromAmounts :: [Amount] -> Either String (Map CommoditySymbol AmountStyle)

-- | Given a list of amount styles (assumed to be from parsed amounts in a
--   single commodity), in parse order, choose a canonical style.
canonicalStyleFrom :: [AmountStyle] -> AmountStyle

-- | Infer transaction-implied market prices from commodity-exchanging
--   transactions, if any. It's best to call this after transactions have
--   been balanced and posting amounts have appropriate prices attached.
journalInferMarketPricesFromTransactions :: Journal -> Journal

-- | Convert all this journal's amounts to cost using their attached
--   prices, if any.
journalToCost :: ConversionOp -> Journal -> Journal

-- | Add equity postings inferred from costs, where needed and possible.
--   See hledger manual > Cost reporting.
journalInferEquityFromCosts :: Bool -> Journal -> Journal

-- | Add costs inferred from equity conversion postings, where needed and
--   possible. See hledger manual > Cost reporting.
journalInferCostsFromEquity :: Journal -> Either String Journal

-- | Do just the internal tagging that is normally done by
--   journalInferCostsFromEquity, identifying equity conversion postings
--   and, in particular, postings which have redundant costs. Tagging the
--   latter is useful as it allows them to be ignored during transaction
--   balancedness checking. And that allows journalInferCostsFromEquity to
--   be postponed till after transaction balancing, when it will have more
--   information (amounts) to work with.
journalMarkRedundantCosts :: Journal -> Either String Journal

-- | The fully specified exact date span enclosing the dates (primary or
--   secondary) of all this journal's transactions and postings, or
--   DateSpan Nothing Nothing if there are none.
journalDateSpan :: Bool -> Journal -> DateSpan

-- | The fully specified date span enclosing the dates (primary and
--   secondary) of all this journal's transactions and postings, or
--   DateSpan Nothing Nothing if there are none.
journalDateSpanBothDates :: Journal -> DateSpan

-- | The earliest of this journal's transaction and posting dates, or
--   Nothing if there are none.
journalStartDate :: Bool -> Journal -> Maybe Day

-- | The "exclusive end date" of this journal: the day following its latest
--   transaction or posting date, or Nothing if there are none.
journalEndDate :: Bool -> Journal -> Maybe Day

-- | The latest of this journal's transaction and posting dates, or Nothing
--   if there are none.
journalLastDay :: Bool -> Journal -> Maybe Day

-- | Apply the pivot transformation to all postings in a journal, replacing
--   their account name by their value for the given field or tag.
journalPivot :: Text -> Journal -> Journal

-- | Apply some account aliases to all posting account names in the
--   journal, as described by accountNameApplyAliases. This can fail due to
--   a bad replacement pattern in a regular expression alias.
journalApplyAliases :: [AccountAlias] -> Journal -> Either RegexError Journal
samplejournal :: Journal
samplejournalMaybeExplicit :: Bool -> Journal
tests_Journal :: TestTree

-- | Check that all the journal's postings are to accounts with a unique
--   leaf name. Otherwise, return an error message for the first offending
--   posting.
journalCheckUniqueleafnames :: Journal -> Either String ()

-- | Check that all the journal's postings are to accounts with account
--   directives, returning an error message otherwise.
journalCheckAccounts :: Journal -> Either String ()

-- | Check that all the commodities used in this journal's postings have
--   been declared by commodity directives, returning an error message
--   otherwise.
journalCheckCommodities :: Journal -> Either String ()

-- | Check that all the journal's transactions have payees declared with
--   payee directives, returning an error message otherwise.
journalCheckPayees :: Journal -> Either String ()

-- | Check that all the journal's tags (on accounts, transactions,
--   postings..) have been declared with tag directives, returning an error
--   message otherwise.
journalCheckTags :: Journal -> Either String ()

-- | In each tranaction, check that any conversion postings occur in
--   adjacent pairs.
journalCheckPairedConversionPostings :: Journal -> Either String ()

-- | Check that accounts with balance assertions have no posting more than
--   maxlag days after their latest balance assertion. Today's date is
--   provided for error messages.
journalCheckRecentAssertions :: Day -> Journal -> Either String ()
defbalancingopts :: BalancingOpts

-- | Legacy form of transactionCheckBalanced.
isTransactionBalanced :: BalancingOpts -> Transaction -> Bool

-- | Balance this transaction, ensuring that its postings (and its balanced
--   virtual postings) sum to 0, by inferring a missing amount or
--   conversion price(s) if needed. Or if balancing is not possible,
--   because the amounts don't sum to 0 or because there's more than one
--   missing amount, return an error message.
--   
--   Transactions with balance assignments can have more than one missing
--   amount; to balance those you should use the more powerful
--   journalBalanceTransactions.
--   
--   The "sum to 0" test is done using commodity display precisions, if
--   provided, so that the result agrees with the numbers users can see.
balanceTransaction :: BalancingOpts -> Transaction -> Either String Transaction

-- | Helper used by balanceTransaction and
--   balanceTransactionWithBalanceAssignmentAndCheckAssertionsB; use one of
--   those instead. It also returns a list of accounts and amounts that
--   were inferred.
balanceTransactionHelper :: BalancingOpts -> Transaction -> Either String (Transaction, [(AccountName, MixedAmount)])

-- | Check any balance assertions in the journal and return an error
--   message if any of them fail (or if the transaction balancing they
--   require fails).
journalCheckBalanceAssertions :: Journal -> Maybe String

-- | Infer any missing amounts and/or conversion costs (as needed to
--   balance transactions and satisfy balance assignments); and check that
--   all transactions are balanced; and (optional) check that all balance
--   assertions pass. Or, return an error message (just the first error
--   encountered).
--   
--   Assumes journalStyleAmounts has been called, since amount styles
--   affect transaction balancing.
--   
--   This does multiple things at once because amount inferring, balance
--   assignments, balance assertions and posting dates are interdependent.
journalBalanceTransactions :: BalancingOpts -> Journal -> Either String Journal
tests_Balancing :: TestTree
definputopts :: InputOpts

-- | Get the Maybe the DateSpan to generate forecast options from. This
--   begins on: - the start date supplied to the `--forecast` argument, if
--   present - otherwise, the later of - the report start date if specified
--   with -b-pdate: - the day after the latest normal (non-periodic)
--   transaction in the journal, if any - otherwise today. It ends on: -
--   the end date supplied to the `--forecast` argument, if present -
--   otherwise the report end date if specified with -e-pdate: -
--   otherwise 180 days (6 months) from today.
forecastPeriod :: InputOpts -> Journal -> Maybe DateSpan
nullacct :: Account

-- | Derive 1. an account tree and 2. each account's total exclusive and
--   inclusive changes from a list of postings. This is the core of the
--   balance command (and of *ledger). The accounts are returned as a list
--   in flattened tree order, and also reference each other as a tree. (The
--   first account is the root of the tree.)
accountsFromPostings :: [Posting] -> [Account]

-- | Convert a list of account names to a tree of Account objects, with
--   just the account names filled in. A single root account with the given
--   name is added.
accountTree :: AccountName -> [AccountName] -> Account

-- | Get this account's parent accounts, from the nearest up to the root.
parentAccounts :: Account -> [Account]

-- | List the accounts at each level of the account tree.
accountsLevels :: Account -> [[Account]]

-- | Map a (non-tree-structure-modifying) function over this and sub
--   accounts.
mapAccounts :: (Account -> Account) -> Account -> Account

-- | Is the predicate true on any of this account or its subaccounts ?
anyAccounts :: (Account -> Bool) -> Account -> Bool

-- | Add subaccount-inclusive balances to an account tree.
sumAccounts :: Account -> Account

-- | Remove all subaccounts below a certain depth.
clipAccounts :: Int -> Account -> Account

-- | Remove subaccounts below the specified depth, aggregating their
--   balance at the depth limit (accounts at the depth limit will have any
--   sub-balances merged into their exclusive balance). If the depth is
--   Nothing, return the original accounts
clipAccountsAndAggregate :: Maybe Int -> [Account] -> [Account]

-- | Remove all leaf accounts and subtrees matching a predicate.
pruneAccounts :: (Account -> Bool) -> Account -> Maybe Account

-- | Flatten an account tree into a list, which is sometimes convenient.
--   Note since accounts link to their parents/subs, the tree's structure
--   remains intact and can still be used. It's a tree/list!
flattenAccounts :: Account -> [Account]

-- | Filter an account tree (to a list).
filterAccounts :: (Account -> Bool) -> Account -> [Account]

-- | Sort each group of siblings in an account tree by inclusive amount, so
--   that the accounts with largest normal balances are listed first. The
--   provided normal balance sign determines whether normal balances are
--   negative or positive, affecting the sort order. Ie, if balances are
--   normally negative, then the most negative balances sort first, and
--   vice versa.
sortAccountTreeByAmount :: NormalSign -> Account -> Account

-- | Add extra info for this account derived from the Journal's account
--   directives, if any (comment, tags, declaration order..).
accountSetDeclarationInfo :: Journal -> Account -> Account

-- | Sort account names by the order in which they were declared in the
--   journal, at each level of the account tree (ie within each group of
--   siblings). Undeclared accounts are sorted last and alphabetically.
--   This is hledger's default sort for reports organised by account. The
--   account list is converted to a tree temporarily, adding any missing
--   parents; these can be kept (suitable for a tree-mode report) or
--   removed (suitable for a flat-mode report).
sortAccountNamesByDeclaration :: Journal -> Bool -> [AccountName] -> [AccountName]

-- | Search an account list by name.
lookupAccount :: AccountName -> [Account] -> Maybe Account
printAccounts :: Account -> IO ()
showAccounts :: Account -> String
showAccountsBoringFlag :: Account -> String
nullledger :: Ledger

-- | Filter a journal's transactions with the given query, then build a
--   Ledger, containing the journal plus the tree of all its
--   accounts with their subaccount-inclusive and subaccount-exclusive
--   balances. If the query includes a depth limit, the ledger's journal
--   will be depth limited, but the ledger's account tree will not.
ledgerFromJournal :: Query -> Journal -> Ledger

-- | List a ledger's account names.
ledgerAccountNames :: Ledger -> [AccountName]

-- | Get the named account from a ledger.
ledgerAccount :: Ledger -> AccountName -> Maybe Account

-- | Get this ledger's root account, which is a dummy "root" account above
--   all others. This should always be first in the account list, if
--   somehow not this returns a null account.
ledgerRootAccount :: Ledger -> Account

-- | List a ledger's top-level accounts (the ones below the root), in tree
--   order.
ledgerTopAccounts :: Ledger -> [Account]

-- | List a ledger's bottom-level (subaccount-less) accounts, in tree
--   order.
ledgerLeafAccounts :: Ledger -> [Account]

-- | List a ledger's postings, in the order parsed.
ledgerPostings :: Ledger -> [Posting]

-- | The (fully specified) date span containing all the ledger's (filtered)
--   transactions, or DateSpan Nothing Nothing if there are none.
ledgerDateSpan :: Ledger -> DateSpan

-- | All commodities used in this ledger.
ledgerCommodities :: Ledger -> [CommoditySymbol]
tests_Ledger :: TestTree
tests_Data :: TestTree
defreportopts :: ReportOpts

-- | Generate a ReportOpts from raw command-line input, given a day. This
--   will fail with a usage error if it is passed - an invalid --format
--   argument, - an invalid --value argument, - if --valuechange is called
--   with a valuation type other than -V/--value=end. - an invalid --pretty
--   argument,
rawOptsToReportOpts :: Day -> RawOpts -> ReportOpts
defreportspec :: ReportSpec

-- | Set the default ConversionOp.
setDefaultConversionOp :: ConversionOp -> ReportSpec -> ReportSpec
balanceAccumulationOverride :: RawOpts -> Maybe BalanceAccumulation

-- | Get the report interval, if any, specified by the last of -p/--period,
--   -D--daily, -W--weekly, -M/--monthly etc. options. An interval
--   from --period counts only if it is explicitly defined.
intervalFromRawOpts :: RawOpts -> Interval

-- | Reduce a list of statuses to just one of each status, and if all
--   statuses are present return the empty list.
simplifyStatuses :: Ord a => [a] -> [a]

-- | Add/remove this status from the status list. Used by hledger-ui.
reportOptsToggleStatus :: Status -> ReportOpts -> ReportOpts

-- | Select the Transaction date accessor based on --date2.
transactionDateFn :: ReportOpts -> Transaction -> Day

-- | Select the Posting date accessor based on --date2.
postingDateFn :: ReportOpts -> Posting -> Day

-- | Report which date we will report on based on --date2.
whichDate :: ReportOpts -> WhichDate

-- | Legacy-compatible convenience aliases for accountlistmode_.
tree_ :: ReportOpts -> Bool
flat_ :: ReportOpts -> Bool

-- | Convert a Journal's amounts to cost and/or to value (see
--   journalApplyValuationFromOpts), and filter by the
--   ReportSpec Query.
--   
--   We make sure to first filter by amt: and cur: terms, then value the
--   Journal, then filter by the remaining terms.
journalValueAndFilterPostings :: ReportSpec -> Journal -> Journal

-- | Like journalValueAndFilterPostings, but takes a
--   PriceOracle as an argument.
journalValueAndFilterPostingsWith :: ReportSpec -> Journal -> PriceOracle -> Journal

-- | Convert this journal's postings' amounts to cost and/or to value, if
--   specified by options (-B--cost-V-X--value etc.). Strip
--   prices if not needed. This should be the main stop for performing
--   costing and valuation. The exception is whenever you need to perform
--   valuation _after_ summing up amounts, as in a historical balance
--   report with --value=end. valuationAfterSum will check for this
--   condition.
journalApplyValuationFromOpts :: ReportSpec -> Journal -> Journal

-- | Like journalApplyValuationFromOpts, but takes PriceOracle as an
--   argument.
journalApplyValuationFromOptsWith :: ReportSpec -> Journal -> PriceOracle -> Journal

-- | Select the Account valuation functions required for performing
--   valuation after summing amounts. Used in MultiBalanceReport to value
--   historical and similar reports.
mixedAmountApplyValuationAfterSumFromOptsWith :: ReportOpts -> Journal -> PriceOracle -> DateSpan -> MixedAmount -> MixedAmount

-- | If the ReportOpts specify that we are performing valuation after
--   summing amounts, return Just of the commodity symbol we're converting
--   to, Just Nothing for the default, and otherwise return Nothing. Used
--   for example with historical reports with --value=end.
valuationAfterSum :: ReportOpts -> Maybe (Maybe CommoditySymbol)

-- | Convert report options to a query, ignoring any non-flag command line
--   arguments.
queryFromFlags :: ReportOpts -> Query

-- | The effective report span is the start and end dates specified by
--   options or queries, or otherwise the earliest and latest transaction
--   or posting dates in the journal. If no dates are specified by
--   options/queries and the journal is empty, returns the null date span.
--   Also return the intervals if they are requested.
reportSpan :: Journal -> ReportSpec -> (DateSpan, [DateSpan])

-- | Like reportSpan, but uses both primary and secondary dates when
--   calculating the span.
reportSpanBothDates :: Journal -> ReportSpec -> (DateSpan, [DateSpan])
reportStartDate :: Journal -> ReportSpec -> Maybe Day
reportEndDate :: Journal -> ReportSpec -> Maybe Day
reportPeriodStart :: ReportSpec -> Maybe Day
reportPeriodOrJournalStart :: ReportSpec -> Journal -> Maybe Day
reportPeriodLastDay :: ReportSpec -> Maybe Day
reportPeriodOrJournalLastDay :: ReportSpec -> Journal -> Maybe Day

-- | Make a name for the given period in a multiperiod report, given the
--   type of balance being reported and the full set of report periods.
--   This will be used as a column heading (or row heading, in a register
--   summary report). We try to pick a useful name as follows:
--   
--   
--   
- ending-balance reports: the period's end date
--   
- balance change reports where the periods are months and all in the
--   same year: the short month name in the current locale
--   
- all other balance change reports: a description of the datespan,
--   abbreviated to compact form if possible (see showDateSpan).
--   
reportPeriodName :: BalanceAccumulation -> [DateSpan] -> DateSpan -> Text

-- | Apply a function over a lens, but report on failure.
overEither :: ((a -> Either e b) -> s -> Either e t) -> (a -> b) -> s -> Either e t

-- | Set a field using a lens, but report on failure.
setEither :: ((a -> Either e b) -> s -> Either e t) -> b -> s -> Either e t

-- | Generate a ReportSpec from a set of ReportOpts on a given day.
reportOptsToSpec :: Day -> ReportOpts -> Either String ReportSpec

-- | Update the ReportOpts and the fields derived from it in a ReportSpec,
--   or return an error message if there is a problem such as missing or
--   unparseable options data. This is the safe way to change a ReportSpec,
--   ensuring that all fields (_rsQuery, _rsReportOpts, querystring_, etc.)
--   are in sync.
updateReportSpec :: ReportOpts -> ReportSpec -> Either String ReportSpec

-- | Like updateReportSpec, but takes a ReportOpts-modifying function.
updateReportSpecWith :: (ReportOpts -> ReportOpts) -> ReportSpec -> Either String ReportSpec

-- | Generate a ReportSpec from RawOpts and a provided day, or return an
--   error string if there are regular expression errors.
rawOptsToReportSpec :: Day -> RawOpts -> Either String ReportSpec

-- | Add two PeriodicReportRows, preserving the name of the first.
prrAdd :: Semigroup b => PeriodicReportRow a b -> PeriodicReportRow a b -> PeriodicReportRow a b

-- | Figure out the overall date span of a PeriodicReport
periodicReportSpan :: PeriodicReport a b -> DateSpan

-- | Map a function over the row names.
prMapName :: (a -> b) -> PeriodicReport a c -> PeriodicReport b c

-- | Map a function over the row names, possibly discarding some.
prMapMaybeName :: (a -> Maybe b) -> PeriodicReport a c -> PeriodicReport b c

-- | Construct a flat display name, where the full name is also displayed
--   at depth 1
flatDisplayName :: AccountName -> DisplayName

-- | Construct a tree display name, where only the leaf is displayed at its
--   given depth
treeDisplayName :: AccountName -> DisplayName

-- | Get the full, canonical, name of a PeriodicReportRow tagged by a
--   DisplayName.
prrFullName :: PeriodicReportRow DisplayName a -> AccountName

-- | Get the display name of a PeriodicReportRow tagged by a DisplayName.
prrDisplayName :: PeriodicReportRow DisplayName a -> AccountName

-- | Get the display depth of a PeriodicReportRow tagged by a DisplayName.
prrDepth :: PeriodicReportRow DisplayName a -> Int

-- | Select postings from the journal and add running balance and other
--   information to make a postings report. Used by eg hledger's register
--   command.
postingsReport :: ReportSpec -> Journal -> PostingsReport

-- | Generate one postings report line item, containing the posting, the
--   current running balance, and optionally the posting date and/or the
--   transaction description.
mkpostingsReportItem :: Bool -> Bool -> WhichDate -> Maybe Period -> Posting -> MixedAmount -> PostingsReportItem
tests_PostingsReport :: TestTree

-- | Generate a multicolumn balance report for the matched accounts,
--   showing the change of balance, accumulated balance, or historical
--   balance in each of the specified periods. If the normalbalance_ option
--   is set, it adjusts the sorting and sign of amounts (see ReportOpts and
--   CompoundBalanceCommand). hledger's most powerful and useful report,
--   used by the balance command (in multiperiod mode) and (via
--   compoundBalanceReport) by the bscfis commands.
multiBalanceReport :: ReportSpec -> Journal -> MultiBalanceReport

-- | A helper for multiBalanceReport. This one takes some extra arguments,
--   a PriceOracle to be used for looking up market prices, and a
--   set of AccountNames which should not be elided. Commands which
--   run multiple reports (bs etc.) can generate the price oracle just once
--   for efficiency, passing it to each report by calling this function
--   directly.
multiBalanceReportWith :: ReportSpec -> Journal -> PriceOracle -> Set AccountName -> MultiBalanceReport

-- | Generate a compound balance report from a list of CBCSubreportSpec.
--   This shares postings between the subreports.
compoundBalanceReport :: ReportSpec -> Journal -> [CBCSubreportSpec a] -> CompoundPeriodicReport a MixedAmount

-- | A helper for compoundBalanceReport, similar to multiBalanceReportWith.
compoundBalanceReportWith :: ReportSpec -> Journal -> PriceOracle -> [CBCSubreportSpec a] -> CompoundPeriodicReport a MixedAmount

-- | Postings needed to calculate starting balances.
--   
--   Balances at report start date, from all earlier postings which
--   otherwise match the query. These balances are unvalued. TODO: Do we
--   want to check whether to bother calculating these? isHistorical and
--   startDate is not nothing, otherwise mempty? This currently gives a
--   failure with some totals which are supposed to be 0 being blank.
startingPostings :: ReportSpec -> Journal -> PriceOracle -> DateSpan -> [Posting]

-- | Remove any date queries and insert queries from the report span. The
--   user's query expanded to the report span if there is one (otherwise
--   any date queries are left as-is, which handles the hledger-ui+future
--   txns case above).
makeReportQuery :: ReportSpec -> DateSpan -> ReportSpec

-- | Group postings, grouped by their column
getPostingsByColumn :: ReportSpec -> Journal -> PriceOracle -> [DateSpan] -> [(DateSpan, [Posting])]

-- | Gather postings matching the query within the report period.
getPostings :: ReportSpec -> Journal -> PriceOracle -> [Posting]

-- | Lay out a set of postings grouped by date span into a regular matrix
--   with rows given by AccountName and columns by DateSpan, then generate
--   a MultiBalanceReport from the columns.
generateMultiBalanceReport :: ReportSpec -> Journal -> PriceOracle -> Set AccountName -> [(DateSpan, [Posting])] -> HashMap AccountName Account -> MultiBalanceReport

-- | Sort the rows by amount or by account declaration order.
sortRows :: ReportOpts -> Journal -> [MultiBalanceReportRow] -> [MultiBalanceReportRow]

-- | A sorting helper: sort a list of things (eg report rows) keyed by
--   account name to match the provided ordering of those same account
--   names.
sortRowsLike :: [AccountName] -> [PeriodicReportRow DisplayName b] -> [PeriodicReportRow DisplayName b]

-- | Given a table representing a multi-column balance report (for example,
--   made using balanceReportAsTable), render it in a format
--   suitable for console output. Amounts with more than two commodities
--   will be elided unless --no-elide is used.
balanceReportTableAsText :: ReportOpts -> Table Text Text WideBuilder -> Builder
tests_MultiBalanceReport :: TestTree

-- | Select transactions for an entries report.
entriesReport :: ReportSpec -> Journal -> EntriesReport
tests_EntriesReport :: TestTree

-- | Calculate per-account, per-period budget (balance change) goals from
--   all periodic transactions, calculate actual balance changes from the
--   regular transactions, and compare these to get a BudgetReport.
--   Unbudgeted accounts may be hidden or renamed (see
--   journalWithBudgetAccountNames).
budgetReport :: ReportSpec -> BalancingOpts -> DateSpan -> Journal -> BudgetReport

-- | Combine a per-account-and-subperiod report of budget goals, and one of
--   actual change amounts, into a budget performance report. The two
--   reports should have the same report interval, but need not have
--   exactly the same account rows or date columns. (Cells in the combined
--   budget report can be missing a budget goal, an actual amount, or
--   both.) The combined report will include:
--   
--   
--   
- consecutive subperiods at the same interval as the two reports,
--   spanning the period of both reports
--   
- all accounts mentioned in either report, sorted by account code or
--   account name or amount as appropriate.
--   
combineBudgetAndActual :: ReportOpts -> Journal -> MultiBalanceReport -> MultiBalanceReport -> BudgetReport

-- | Render a budget report as plain text suitable for console output.
budgetReportAsText :: ReportOpts -> BudgetReport -> Text

-- | Build a Table from a multi-column balance report.
budgetReportAsTable :: ReportOpts -> BudgetReport -> Table Text Text WideBuilder

-- | Render a budget report as CSV. Like multiBalanceReportAsCsv, but
--   includes alternating actual and budget amount columns.
budgetReportAsCsv :: ReportOpts -> BudgetReport -> [[Text]]
tests_BudgetReport :: TestTree

-- | When true (the default), this makes balance --flat reports and their
--   implementation clearer. Single/multi-col balance reports currently
--   aren't all correct if this is false.
flatShowsExclusiveBalance :: Bool

-- | Enabling this makes balance --flat --empty also show parent accounts
--   without postings, in addition to those with postings and a zero
--   balance. Disabling it shows only the latter. No longer supported, but
--   leave this here for a bit. flatShowsPostinglessAccounts = True
--   
--   Generate a simple balance report, containing the matched accounts and
--   their balances (change of balance) during the specified period. If the
--   normalbalance_ option is set, it adjusts the sorting and sign of
--   amounts (see ReportOpts and CompoundBalanceCommand).
balanceReport :: ReportSpec -> Journal -> BalanceReport
tests_BalanceReport :: TestTree
triOrigTransaction :: (a, b, c, d, e, f) -> a
triDate :: (a, Transaction, c, d, e, f) -> Day
triAmount :: (a, b, c, d, e, f) -> e
triBalance :: (a, b, c, d, e, f) -> f
triCommodityAmount :: CommoditySymbol -> (a, b, c, d, MixedAmount, f) -> MixedAmount
triCommodityBalance :: CommoditySymbol -> (a, b, c, d, e, MixedAmount) -> MixedAmount
accountTransactionsReport :: ReportSpec -> Journal -> Query -> AccountTransactionsReport

-- | Generate transactions report items from a list of transactions, using
--   the provided user-specified report query, a query specifying which
--   account to use as the focus, a starting balance, and a sign-setting
--   function. Each transaction is accompanied by the date that should be
--   shown for it in the report. This is not necessarily the transaction
--   date - see transactionRegisterDate.
accountTransactionsReportItems :: Query -> Query -> MixedAmount -> (MixedAmount -> MixedAmount) -> (AccountName -> Maybe AccountType) -> [(Day, Transaction)] -> [AccountTransactionsReportItem]

-- | What date should be shown for a transaction in an account register
--   report ? This will be in context of a particular account (the "this
--   account" query) and any additional report query. It could be:
--   
--   
--   
- if postings are matched by both thisacctq and reportq, the
--   earliest of those matched postings' dates (or their secondary dates if
--   --date2 was used)
--   
- the transaction date, or its secondary date if --date2 was
--   used.
--   
transactionRegisterDate :: WhichDate -> Query -> Query -> Transaction -> Day

-- | Split an account transactions report whose items may involve several
--   commodities, into one or more single-commodity account transactions
--   reports.
accountTransactionsReportByCommodity :: AccountTransactionsReport -> [(CommoditySymbol, AccountTransactionsReport)]
tests_AccountTransactionsReport :: TestTree
tests_Reports :: TestTree

-- | Parse an InputOpts from a RawOpts and a provided date. This will fail
--   with a usage error if the forecast period expression cannot be parsed.
rawOptsToInputOpts :: Day -> RawOpts -> InputOpts

-- | Given a parser to ParsedJournal, input options, file path and content:
--   run the parser on the content, and finalise the result to get a
--   Journal; or throw an error.
parseAndFinaliseJournal :: ErroringJournalParser IO ParsedJournal -> InputOpts -> FilePath -> Text -> ExceptT String IO Journal

-- | Given a parser to ParsedJournal, input options, file path and content:
--   run the parser on the content. This is all steps of
--   parseAndFinaliseJournal without the finalisation step, and is
--   used when you need to perform other actions before finalisation, as in
--   parsing Timeclock and Timedot files.
initialiseAndParseJournal :: ErroringJournalParser IO ParsedJournal -> InputOpts -> FilePath -> Text -> ExceptT String IO Journal

-- | Post-process a Journal that has just been parsed or generated, in this
--   order:
--   
--   
--   
- add misc info (file path, read time)
--   
- reverse transactions into their original parse order
--   
- apply canonical commodity styles
--   
- add tags from account directives to postings' tags
--   
- add forecast transactions if enabled
--   
- add tags from account directives to postings' tags (again to
--   affect forecast transactions)
--   
- add auto postings if enabled
--   
- add tags from account directives to postings' tags (again to
--   affect auto postings)
--   
- evaluate balance assignments and balance each transaction
--   
- check balance assertions if enabled
--   
- infer equity postings in conversion transactions if enabled
--   
- infer market prices from costs if enabled
--   
- check all accounts have been declared if in strict mode
--   
- check all commodities have been declared if in strict mode
--   
journalFinalise :: InputOpts -> FilePath -> Text -> ParsedJournal -> ExceptT String IO Journal

-- | Apply any auto posting rules to generate extra postings on this
--   journal's transactions. With a true first argument, adds visible tags
--   to generated postings and modified transactions.
journalAddAutoPostings :: Bool -> Day -> BalancingOpts -> Journal -> Either String Journal

-- | Generate periodic transactions from all periodic transaction rules in
--   the journal. These transactions are added to the in-memory Journal
--   (but not the on-disk file).
--   
--   The start & end date for generated periodic transactions are
--   determined in a somewhat complicated way; see the hledger manual ->
--   Periodic transactions.
journalAddForecast :: Bool -> Maybe DateSpan -> Journal -> Journal
setYear :: forall (m :: Type -> Type). Year -> JournalParser m ()
getYear :: forall (m :: Type -> Type). JournalParser m (Maybe Year)
setDefaultCommodityAndStyle :: forall (m :: Type -> Type). (CommoditySymbol, AmountStyle) -> JournalParser m ()
getDefaultCommodityAndStyle :: forall (m :: Type -> Type). JournalParser m (Maybe (CommoditySymbol, AmountStyle))

-- | Get amount style associated with default currency.
--   
--   Returns AmountStyle used to defined by a latest default
--   commodity directive prior to current position within this file or its
--   parents.
getDefaultAmountStyle :: forall (m :: Type -> Type). JournalParser m (Maybe AmountStyle)

-- | Get the AmountStyle declared by the most recently parsed (in
--   the current or parent files, prior to the current position) commodity
--   directive for the given commodity, if any.
getAmountStyle :: forall (m :: Type -> Type). CommoditySymbol -> JournalParser m (Maybe AmountStyle)
addDeclaredAccountTags :: forall (m :: Type -> Type). AccountName -> [Tag] -> JournalParser m ()
addDeclaredAccountType :: forall (m :: Type -> Type). AccountName -> AccountType -> JournalParser m ()
pushParentAccount :: forall (m :: Type -> Type). AccountName -> JournalParser m ()
popParentAccount :: forall (m :: Type -> Type). JournalParser m ()
getParentAccount :: forall (m :: Type -> Type). JournalParser m AccountName
addAccountAlias :: MonadState Journal m => AccountAlias -> m ()
getAccountAliases :: MonadState Journal m => m [AccountAlias]
clearAccountAliases :: MonadState Journal m => m ()
journalAddFile :: (FilePath, Text) -> Journal -> Journal
statusp :: forall (m :: Type -> Type). TextParser m Status
codep :: forall (m :: Type -> Type). TextParser m Text

-- | Parse possibly empty text until a semicolon or newline. Whitespace is
--   preserved (for now - perhaps helps preserve alignment of same-line
--   comments ?).
descriptionp :: forall (m :: Type -> Type). TextParser m Text

-- | Parse a date in YYYY-MM-DD format. Slash (/) and period (.) are also
--   allowed as separators. The year may be omitted if a default year has
--   been set. Leading zeroes may be omitted.
datep :: forall (m :: Type -> Type). JournalParser m Day

-- | Parse a date and time in YYYY-MM-DD HH:MM[:SS][+-ZZZZ] format. Slash
--   (/) and period (.) are also allowed as date separators. The year may
--   be omitted if a default year has been set. Seconds are optional. The
--   timezone is optional and ignored (the time is always interpreted as a
--   local time). Leading zeroes may be omitted (except in a timezone).
datetimep :: forall (m :: Type -> Type). JournalParser m LocalTime
secondarydatep :: forall (m :: Type -> Type). Day -> TextParser m Day

-- | Parse an account name (plus one following space if present), then
--   apply any parent account prefix and/or account aliases currently in
--   effect, in that order. (Ie first add the parent account prefix, then
--   rewrite with aliases). This calls error if any account alias with an
--   invalid regular expression exists.
modifiedaccountnamep :: forall (m :: Type -> Type). JournalParser m AccountName

-- | Parse an account name, plus one following space if present. Account
--   names have one or more parts separated by the account separator
--   character, and are terminated by two or more spaces (or end of input).
--   Each part is at least one character long, may have single spaces
--   inside it, and starts with a non-whitespace. Note, this means
--   "{account}", "%^!" and ";comment" are all accepted (parent parsers
--   usually prevent/consume the last). It should have required parts to
--   start with an alphanumeric; for now it remains as-is for backwards
--   compatibility.
accountnamep :: forall (m :: Type -> Type). TextParser m AccountName

-- | Parse a single line of possibly empty text enclosed in double quotes.
doublequotedtextp :: forall (m :: Type -> Type). TextParser m Text

-- | Parse possibly empty text, including whitespace, until a comment start
--   (semicolon) or newline.
noncommenttextp :: forall (m :: Type -> Type). TextParser m Text

-- | Parse non-empty text, including whitespace, until a comment start
--   (semicolon) or newline.
noncommenttext1p :: forall (m :: Type -> Type). TextParser m Text

-- | Parse non-empty, single-spaced text starting and ending with
--   non-whitespace, until a double space or newline.
singlespacedtext1p :: forall (m :: Type -> Type). TextParser m Text

-- | Parse non-empty, single-spaced text starting and ending with
--   non-whitespace, until a comment start (semicolon), double space, or
--   newline.
singlespacednoncommenttext1p :: forall (m :: Type -> Type). TextParser m Text

-- | Parse non-empty, single-spaced text starting and ending with
--   non-whitespace, where all characters satisfy the given predicate.
singlespacedtextsatisfying1p :: forall (m :: Type -> Type). (Char -> Bool) -> TextParser m Text

-- | Parse one non-newline whitespace character that is not followed by
--   another one.
singlespacep :: forall (m :: Type -> Type). TextParser m ()

-- | Parse whitespace then an amount, or return the special "missing"
--   marker amount.
spaceandamountormissingp :: forall (m :: Type -> Type). JournalParser m MixedAmount

-- | Parse a single-commodity amount, applying the default commodity if
--   there is no commodity symbol; optionally followed by, in any order: a
--   Ledger-style cost, Ledger-style valuation expression, and/or
--   Ledger-style cost basis, which is one or more of lot cost, lot date,
--   and/or lot note (we loosely call this triple the lot's cost basis).
--   The cost basis makes it a lot rather than just an amount. Both cost
--   basis info and valuation expression are discarded for now. The main
--   amount's sign is significant; here are the possibilities and their
--   interpretation. Also imagine an optional VALUATIONEXPR added to any of
--   these (omitted for clarity): @
--   
--   AMT -- acquiring an amount AMT COST -- acquiring an amount at some
--   cost AMT COST COSTBASIS -- acquiring a lot at some cost, saving its
--   cost basis AMT COSTBASIS COST -- like the above AMT COSTBASIS -- like
--   the above with cost same as the cost basis
--   
--   
--   
- AMT -- releasing an amount
--   
- AMT SELLPRICE -- releasing an amount at some selling price
--   
- AMT SELLPRICE COSTBASISSEL -- releasing a lot at some selling
--   price, selecting it by its cost basis
--   
- AMT COSTBASISSEL SELLPRICE -- like the above
--   
- AMT COSTBASISSEL -- like the above with selling price same as the
--   selected lot's cost basis amount
--   
--   
--   COST/SELLPRICE can be  UNITAMT,  TOTALAMT, ()
--   UNITAMT, or (@@) TOTALAMT. The () are ignored. COSTBASIS is one or
--   more of {LOTCOST}, [LOTDATE], (LOTNOTE), in any order, with LOTCOST
--   defaulting to COST. COSTBASISSEL is one or more of {LOTCOST},
--   [LOTDATE], (LOTNOTE), in any order. {LOTCOST} can be {UNITAMT},
--   {{TOTALAMT}}, {=UNITAMT}, or {{=TOTALAMT}}. The = is ignored.
--   VALUATIONEXPR can be ((VALUE AMOUNT)) or ((VALUE FUNCTION)).
--   
--   @ Ledger amount syntax is really complex. Rule of thumb: curly braces,
--   parentheses, and/or square brackets in an amount means a Ledger-style
--   cost basis is involved.
--   
--   To parse an amount's numeric quantity we need to know which character
--   represents a decimal mark. We find it in one of three ways:
--   
--   
--   
- If a decimal mark has been set explicitly in the journal parse
--   state, we use that
--   
- Or if the journal has a commodity declaration for the amount's
--   commodity, we get the decimal mark from that
--   
- Otherwise we will parse any valid decimal mark appearing in the
--   number, as long as the number appears well formed. (This means we
--   handle files with any supported decimal mark without configuration,
--   but it also allows different decimal marks in different amounts, which
--   is a bit too loose. There's an open issue.)
--   
amountp :: forall (m :: Type -> Type). JournalParser m Amount
amountp' :: forall (m :: Type -> Type). Bool -> JournalParser m Amount

-- | Try to parse a single-commodity amount from a string
parseamount :: String -> Either HledgerParseErrors Amount

-- | Parse a single-commodity amount from a string, or get an error.
parseamount' :: String -> Amount

-- | Like parseamount', but returns a MixedAmount.
parsemixedamount :: String -> Either HledgerParseErrors MixedAmount

-- | Like parseamount', but returns a MixedAmount.
parsemixedamount' :: String -> MixedAmount
commoditysymbolp :: forall (m :: Type -> Type). TextParser m CommoditySymbol

-- | Ledger-style cost notation:  UNITAMT,  TOTALAMT, ()
--   UNITAMT, or (@@) TOTALAMT. The () are ignored.
costp :: forall (m :: Type -> Type). Amount -> JournalParser m AmountPrice
balanceassertionp :: forall (m :: Type -> Type). JournalParser m BalanceAssertion
lotcostp :: forall (m :: Type -> Type). JournalParser m ()

-- | Parse a string representation of a number for its value and display
--   attributes.
--   
--   Some international number formats are accepted, eg either period or
--   comma may be used for the decimal mark, and the other of these may be
--   used for separating digit groups in the integer part. See
--   http://en.wikipedia.org/wiki/Decimal_separator for more
--   examples.
--   
--   This returns: the parsed numeric value, the precision (number of
--   digits seen following the decimal mark), the decimal mark character
--   used if any, and the digit group style if any.
numberp :: forall (m :: Type -> Type). Maybe AmountStyle -> TextParser m (Quantity, Word8, Maybe Char, Maybe DigitGroupStyle)

-- | Interpret a raw number as a decimal number.
--   
--   Returns: - the decimal number - the precision (number of digits after
--   the decimal point) - the decimal point character, if any - the digit
--   group style, if any (digit group character and sizes of digit groups)
fromRawNumber :: RawNumber -> Maybe Integer -> Either String (Quantity, Word8, Maybe Char, Maybe DigitGroupStyle)

-- | Parse and interpret the structure of a number without external hints.
--   Numbers are digit strings, possibly separated into digit groups by one
--   of two types of separators. (1) Numbers may optionally have a decimal
--   mark, which may be either a period or comma. (2) Numbers may
--   optionally contain digit group marks, which must all be either a
--   period, a comma, or a space.
--   
--   It is our task to deduce the characters used as decimal mark and digit
--   group mark, based on the allowed syntax. For instance, we make use of
--   the fact that a decimal mark can occur at most once and must be to the
--   right of all digit group marks.
--   
--   
--   >>> parseTest rawnumberp "1,234,567.89"
--   Right (WithSeparators ',' ["1","234","567"] (Just ('.',"89")))
--   
--   >>> parseTest rawnumberp "1,000"
--   Left (AmbiguousNumber "1" ',' "000")
--   
--   >>> parseTest rawnumberp "1 000"
--   Right (WithSeparators ' ' ["1","000"] Nothing)
--   
rawnumberp :: forall (m :: Type -> Type). TextParser m (Either AmbiguousNumber RawNumber)
multilinecommentp :: forall (m :: Type -> Type). TextParser m ()

-- | A blank or comment line in journal format: a line that's empty or
--   containing only whitespace or whose first non-whitespace character is
--   semicolon, hash, or star.
emptyorcommentlinep :: forall (m :: Type -> Type). TextParser m ()

-- | Is this a character that, as the first non-whitespace on a line,
--   starts a comment line ?
isLineCommentStart :: Char -> Bool

-- | Is this a character that, appearing anywhere within a line, starts a
--   comment ?
isSameLineCommentStart :: Char -> Bool

-- | Parse the text of a (possibly multiline) comment following a journal
--   item.
--   
--   
--   >>> rtp followingcommentp ""   -- no comment
--   Right ""
--   
--   >>> rtp followingcommentp ";"    -- just a (empty) same-line comment. newline is added
--   Right "\n"
--   
--   >>> rtp followingcommentp ";  \n"
--   Right "\n"
--   
--   >>> rtp followingcommentp ";\n ;\n"  -- a same-line and a next-line comment
--   Right "\n\n"
--   
--   >>> rtp followingcommentp "\n ;\n"  -- just a next-line comment. Insert an empty same-line comment so the next-line comment doesn't become a same-line comment.
--   Right "\n\n"
--   
followingcommentp :: forall (m :: Type -> Type). TextParser m Text

-- | Parse a transaction comment and extract its tags.
--   
--   The first line of a transaction may be followed by comments, which
--   begin with semicolons and extend to the end of the line. Transaction
--   comments may span multiple lines, but comment lines below the
--   transaction must be preceded by leading whitespace.
--   
--   200011 ; a transaction comment starting on the same line ... ;
--   extending to the next line account1 $1 account2
--   
--   Tags are name-value pairs.
--   
--   
--   >>> let getTags (_,tags) = tags
--   
--   >>> let parseTags = fmap getTags . rtp transactioncommentp
--   
--   
--   
--   >>> parseTags "; name1: val1, name2:all this is value2"
--   Right [("name1","val1"),("name2","all this is value2")]
--   
--   
--   A tag's name must be immediately followed by a colon, without
--   separating whitespace. The corresponding value consists of all the
--   text following the colon up until the next colon or newline, stripped
--   of leading and trailing whitespace.
transactioncommentp :: forall (m :: Type -> Type). TextParser m (Text, [Tag])
commenttagsp :: forall (m :: Type -> Type). TextParser m [Tag]

-- | Parse a posting comment and extract its tags and dates.
--   
--   Postings may be followed by comments, which begin with semicolons and
--   extend to the end of the line. Posting comments may span multiple
--   lines, but comment lines below the posting must be preceded by leading
--   whitespace.
--   
--   200011 account1 $1 ; a posting comment starting on the same
--   line ... ; extending to the next line
--   
--   account2 ; a posting comment beginning on the next line
--   
--   Tags are name-value pairs.
--   
--   
--   >>> let getTags (_,tags,_,_) = tags
--   
--   >>> let parseTags = fmap getTags . rtp (postingcommentp Nothing)
--   
--   
--   
--   >>> parseTags "; name1: val1, name2:all this is value2"
--   Right [("name1","val1"),("name2","all this is value2")]
--   
--   
--   A tag's name must be immediately followed by a colon, without
--   separating whitespace. The corresponding value consists of all the
--   text following the colon up until the next colon or newline, stripped
--   of leading and trailing whitespace.
--   
--   Posting dates may be expressed with "date"/"date2" tags or with
--   bracketed date syntax. Posting dates will inherit their year from the
--   transaction date if the year is not specified. We throw parse errors
--   on invalid dates.
--   
--   
--   >>> let getDates (_,_,d1,d2) = (d1, d2)
--   
--   >>> let parseDates = fmap getDates . rtp (postingcommentp (Just 2000))
--   
--   
--   
--   >>> parseDates "; date: 1/2, date2: 1999/12/31"
--   Right (Just 2000-01-02,Just 1999-12-31)
--   
--   >>> parseDates "; [1/2=1999/12/31]"
--   Right (Just 2000-01-02,Just 1999-12-31)
--   
--   
--   Example: tags, date tags, and bracketed dates >>> rtp
--   (postingcommentp (Just 2000)) "; a:b, date:34, [=56]" Right
--   ("a:b, date:34, [=56]n",[("a","b"),("date","3/4")],Just
--   2000-03-04,Just 2000-05-06)
--   
--   Example: extraction of dates from date tags ignores trailing text
--   >>> rtp (postingcommentp (Just 2000)) "; date:34=56"
--   Right ("date:34=56n",[("date","34=56")],Just
--   2000-03-04,Nothing)
postingcommentp :: forall (m :: Type -> Type). Maybe Year -> TextParser m (Text, [Tag], Maybe Day, Maybe Day)

-- | Parse Ledger-style bracketed posting dates ([DATE=DATE2]), as "date"
--   and/or "date2" tags. Anything that looks like an attempt at this (a
--   square-bracketed sequence of 0123456789/-.= containing at least one
--   digit and one date separator) is also parsed, and will throw an
--   appropriate error.
--   
--   The dates are parsed in full here so that errors are reported in the
--   right position. A missing year in DATE can be inferred if a default
--   date is provided. A missing year in DATE2 will be inferred from DATE.
--   
--   
--   >>> either (Left . customErrorBundlePretty) Right $ rtp (bracketeddatetagsp Nothing) "[2016/1/2=3/4]"
--   Right [("date",2016-01-02),("date2",2016-03-04)]
--   
--   
--   
--   >>> either (Left . customErrorBundlePretty) Right $ rtp (bracketeddatetagsp Nothing) "[1]"
--   Left ...not a bracketed date...
--   
--   
--   
--   >>> either (Left . customErrorBundlePretty) Right $ rtp (bracketeddatetagsp Nothing) "[2016/1/32]"
--   Left ...1:2:...This date is invalid...
--   
--   
--   
--   >>> either (Left . customErrorBundlePretty) Right $ rtp (bracketeddatetagsp Nothing) "[1/31]"
--   Left ...1:2:...The partial date 1/31 can not be parsed...
--   
--   
--   
--   >>> either (Left . customErrorBundlePretty) Right $ rtp (bracketeddatetagsp Nothing) "[0123456789/-.=/-.=]"
--   Left ...1:13:...expecting month or day...
--   
bracketeddatetagsp :: forall (m :: Type -> Type). Maybe Year -> TextParser m [(TagName, Day)]

-- | Get the account name aliases from options, if any.
aliasesFromOpts :: InputOpts -> [AccountAlias]
accountaliasp :: forall (m :: Type -> Type). TextParser m AccountAlias
tests_Common :: TestTree

-- | Run a journal parser in some monad. See also: parseWithState.
runJournalParser :: Monad m => JournalParser m a -> Text -> m (Either HledgerParseErrors a)

-- | 
--   findReader mformat mpath
--   
--   
--   Find the reader named by mformat, if provided. Or, if a file
--   path is provided, find the first reader that handles its file
--   extension, if any.
findReader :: forall (m :: Type -> Type). MonadIO m => Maybe StorageFormat -> Maybe FilePath -> Maybe (Reader m)

-- | If a filepath is prefixed by one of the reader names and a colon,
--   split that off. Eg "csv:-" -> (Just "csv", "-").
splitReaderPrefix :: PrefixedFilePath -> (Maybe String, FilePath)
tmpostingrulep :: forall (m :: Type -> Type). Maybe Year -> JournalParser m TMPostingRule

-- | Read the default journal file specified by the environment, or raise
--   an error.
defaultJournal :: IO Journal

-- | Get the default journal file path specified by the environment. Like
--   ledger, we look first for the LEDGER_FILE environment variable, and if
--   that does not exist, for the legacy LEDGER environment variable. If
--   neither is set, or the value is blank, return the hard-coded default,
--   which is .hledger.journal in the users's home directory (or
--   in the current directory, if we cannot determine a home directory).
defaultJournalPath :: IO String

-- | 
--   readJournal iopts mfile txt
--   
--   
--   Read a Journal from some text, with strict checks if enabled, or
--   return an error message.
--   
--   The reader (data format) is chosen based on, in this order:
--   
--   
--   
- a reader name provided in iopts
--   
- a reader prefix in the mfile path
--   
- a file extension in mfile
--   
--   
--   If none of these is available, or if the reader name is unrecognised,
--   we use the journal reader (for predictability).
readJournal :: InputOpts -> Maybe FilePath -> Text -> ExceptT String IO Journal

-- | Read a Journal from this file, or from stdin if the file path is -,
--   with strict checks if enabled, or return an error message. The file
--   path can have a READER: prefix.
--   
--   The reader (data format) to use is determined from (in priority
--   order): the mformat_ specified in the input options, if any;
--   the file path's READER: prefix, if any; a recognised file name
--   extension. if none of these identify a known reader, the journal
--   reader is used.
--   
--   The input options can also configure balance assertion checking,
--   automated posting generation, a rules file for converting CSV data,
--   etc.
--   
--   If using --new, and if latest-file writing is enabled in input
--   options, and after passing strict checks if enabled, a .latest.FILE
--   file will be created/updated (for the main file only, not for included
--   files), to remember the latest transaction date (and how many
--   transactions on this date) successfully read.
readJournalFile :: InputOpts -> PrefixedFilePath -> ExceptT String IO Journal

-- | Read a Journal from each specified file path (using
--   readJournalFile) and combine them into one; or return the
--   first error message. Strict checks, if enabled, are deferred till the
--   end. Writing .latest files, if enabled, is also deferred till the end,
--   and happens only if strict checks pass.
--   
--   Combining Journals means concatenating them, basically. The parse
--   state resets at the start of each file, which means that directives
--   & aliases do not affect subsequent sibling or parent files. They
--   do affect included child files though. Also the final parse state
--   saved in the Journal does span all files.
readJournalFiles :: InputOpts -> [PrefixedFilePath] -> ExceptT String IO Journal
readJournalFilesAndLatestDates :: InputOpts -> [PrefixedFilePath] -> ExceptT String IO (Journal, [LatestDatesForFile])

-- | Run the extra -s/--strict checks on a journal, returning the first
--   error message if any of them fail.
journalStrictChecks :: Journal -> Either String ()

-- | An easy version of readJournal which assumes default options,
--   and fails in the IO monad.
readJournal' :: Text -> IO Journal

-- | An easy version of readJournalFile which assumes default
--   options, and fails in the IO monad.
readJournalFile' :: PrefixedFilePath -> IO Journal

-- | An easy version of readJournalFiles' which assumes default
--   options, and fails in the IO monad.
readJournalFiles' :: [PrefixedFilePath] -> IO Journal

-- | Extract ExceptT to the IO monad, failing with an error message if
--   necessary.
orDieTrying :: MonadIO m => ExceptT String m a -> m a

-- | If the specified journal file does not exist (and is not "-"), give a
--   helpful error and quit.
requireJournalFileExists :: FilePath -> IO ()

-- | Ensure there is a journal file at the given path, creating an empty
--   one if needed. On Windows, also ensure that the path contains no
--   trailing dots which could cause data loss (see
--   isWindowsUnsafeDotPath).
ensureJournalFileExists :: FilePath -> IO ()

-- | Save the given latest date(s) seen in the given data FILE, in a hidden
--   file named .latest.FILE, creating it if needed.
saveLatestDates :: LatestDates -> FilePath -> IO ()

-- | Save each file's latest dates.
saveLatestDatesForFiles :: [LatestDatesForFile] -> IO ()
tests_Read :: TestTree
tests_Hledger :: TestTree
assertFailure :: HasCallStack => String -> IO a
assertBool :: HasCallStack => String -> Bool -> Assertion
assertEqual :: (Eq a, Show a, HasCallStack) => String -> a -> a -> Assertion
(@=?) :: (Eq a, Show a, HasCallStack) => a -> a -> Assertion
(@?=) :: (Eq a, Show a, HasCallStack) => a -> a -> Assertion
(@?) :: (AssertionPredicable t, HasCallStack) => t -> String -> Assertion
assertString :: HasCallStack => String -> Assertion
testCaseSteps :: TestName -> ((String -> IO ()) -> Assertion) -> TestTree
testCase :: TestName -> Assertion -> TestTree
testCaseInfo :: TestName -> IO String -> TestTree

-- | Read multiple transactions from the console, prompting for each field,
--   and append them to the journal file. If the journal came from stdin,
--   this command has no effect.
add :: CliOpts -> Journal -> IO ()
foldl1May :: (a -> a -> a) -> [a] -> Maybe a
foldr1May :: (a -> a -> a) -> [a] -> Maybe a
foldl1Note :: Partial => String -> (a -> a -> a) -> [a] -> a
foldr1Note :: Partial => String -> (a -> a -> a) -> [a] -> a
minimumMay :: Ord a => [a] -> Maybe a
maximumMay :: Ord a => [a] -> Maybe a
minimumNote :: (Partial, Ord a) => String -> [a] -> a
maximumNote :: (Partial, Ord a) => String -> [a] -> a
minimumByMay :: (a -> a -> Ordering) -> [a] -> Maybe a
maximumByMay :: (a -> a -> Ordering) -> [a] -> Maybe a
minimumByNote :: Partial => String -> (a -> a -> Ordering) -> [a] -> a
maximumByNote :: Partial => String -> (a -> a -> Ordering) -> [a] -> a

-- | The largest element of a list with respect to the given comparison
--   function. The result is bounded by the value given as the first
--   argument.
maximumBoundBy :: a -> (a -> a -> Ordering) -> [a] -> a

-- | The smallest element of a list with respect to the given comparison
--   function. The result is bounded by the value given as the first
--   argument.
minimumBoundBy :: a -> (a -> a -> Ordering) -> [a] -> a

-- | The largest element of a list. The result is bounded by the value
--   given as the first argument.
maximumBound :: Ord a => a -> [a] -> a

-- | The smallest element of a list. The result is bounded by the value
--   given as the first argument.
minimumBound :: Ord a => a -> [a] -> a

-- | The largest element of a list. The result is bounded by
--   minBound.
maximumBounded :: (Ord a, Bounded a) => [a] -> a

-- | The largest element of a list. The result is bounded by
--   maxBound.
minimumBounded :: (Ord a, Bounded a) => [a] -> a

-- | 
--   findJust op = fromJust . find op
--   
findJust :: (a -> Bool) -> [a] -> a
findJustDef :: a -> (a -> Bool) -> [a] -> a
findJustNote :: Partial => String -> (a -> Bool) -> [a] -> a

-- | New users are recommended to use minimumBound or
--   maximumBound instead.
minimumDef :: Ord a => a -> [a] -> a

-- | New users are recommended to use minimumBound or
--   maximumBound instead.
maximumDef :: Ord a => a -> [a] -> a

-- | New users are recommended to use minimumBoundBy or
--   maximumBoundBy instead.
minimumByDef :: a -> (a -> a -> Ordering) -> [a] -> a

-- | New users are recommended to use minimumBoundBy or
--   maximumBoundBy instead.
maximumByDef :: a -> (a -> a -> Ordering) -> [a] -> a
foldl1Def :: a -> (a -> a -> a) -> [a] -> a
foldr1Def :: a -> (a -> a -> a) -> [a] -> a

-- | Synonym for error. Used for instances where the program has
--   decided to exit because of invalid user input, or the user pressed
--   quit etc. This function allows error to be reserved for
--   programmer errors.
abort :: Partial => String -> a

-- | Identical to tail, namely that fails on an empty list. Useful
--   to avoid the x-partial warning introduced in GHC 9.8.
--   
--   
--   tailErr [] = error "Prelude.tail: empty list"
--   tailErr [1,2,3] = [2,3]
--   
tailErr :: Partial => [a] -> [a]

-- | Identical to head, namely that fails on an empty list. Useful
--   to avoid the x-partial warning introduced in GHC 9.8.
--   
--   
--   headErr [] = error "Prelude.head: empty list"
--   headErr [1,2,3] = 1
--   
headErr :: Partial => [a] -> a

-- | 
--   tailMay [] = Nothing
--   tailMay [1,3,4] = Just [3,4]
--   
tailMay :: [a] -> Maybe [a]

-- | 
--   tailDef [12] [] = [12]
--   tailDef [12] [1,3,4] = [3,4]
--   
tailDef :: [a] -> [a] -> [a]

-- | 
--   tailNote "help me" [] = error "Safe.tailNote [], help me"
--   tailNote "help me" [1,3,4] = [3,4]
--   
tailNote :: Partial => String -> [a] -> [a]

-- | 
--   tailSafe [] = []
--   tailSafe [1,3,4] = [3,4]
--   
tailSafe :: [a] -> [a]
initMay :: [a] -> Maybe [a]
initDef :: [a] -> [a] -> [a]
initNote :: Partial => String -> [a] -> [a]
initSafe :: [a] -> [a]
headMay :: [a] -> Maybe a
lastMay :: [a] -> Maybe a
headNote :: Partial => String -> [a] -> a
lastNote :: Partial => String -> [a] -> a
foldl1May' :: (a -> a -> a) -> [a] -> Maybe a
foldl1Note' :: Partial => String -> (a -> a -> a) -> [a] -> a
scanr1May :: (a -> a -> a) -> [a] -> Maybe [a]
scanl1May :: (a -> a -> a) -> [a] -> Maybe [a]
scanr1Def :: [a] -> (a -> a -> a) -> [a] -> [a]
scanl1Def :: [a] -> (a -> a -> a) -> [a] -> [a]
scanr1Note :: Partial => String -> (a -> a -> a) -> [a] -> [a]
scanl1Note :: Partial => String -> (a -> a -> a) -> [a] -> [a]
cycleMay :: [a] -> Maybe [a]
cycleDef :: [a] -> [a] -> [a]
cycleNote :: Partial => String -> [a] -> [a]

-- | An alternative name for fromMaybe, to fit the naming scheme of
--   this package. Generally using fromMaybe directly would be
--   considered better style.
fromJustDef :: a -> Maybe a -> a
fromJustNote :: Partial => String -> Maybe a -> a
assertNote :: Partial => String -> Bool -> a -> a
atMay :: [a] -> Int -> Maybe a
atDef :: a -> [a] -> Int -> a
atNote :: Partial => String -> [a] -> Int -> a

-- | This function provides a more precise error message than
--   readEither from base.
readEitherSafe :: Read a => String -> Either String a
readMay :: Read a => String -> Maybe a
readDef :: Read a => a -> String -> a

-- | readNote uses readEitherSafe for the error message.
readNote :: (Partial, Read a) => String -> String -> a

-- | 
--   lookupJust key = fromJust . lookup key
--   
lookupJust :: (Eq a, Partial) => a -> [(a, b)] -> b
lookupJustDef :: Eq a => b -> a -> [(a, b)] -> b
lookupJustNote :: (Partial, Eq a) => String -> a -> [(a, b)] -> b

-- | 
--   elemIndexJust op = fromJust . elemIndex op
--   
elemIndexJust :: (Partial, Eq a) => a -> [a] -> Int
elemIndexJustDef :: Eq a => Int -> a -> [a] -> Int
elemIndexJustNote :: (Partial, Eq a) => String -> a -> [a] -> Int

-- | 
--   findIndexJust op = fromJust . findIndex op
--   
findIndexJust :: (a -> Bool) -> [a] -> Int
findIndexJustDef :: Int -> (a -> Bool) -> [a] -> Int
findIndexJustNote :: Partial => String -> (a -> Bool) -> [a] -> Int
toEnumMay :: (Enum a, Bounded a) => Int -> Maybe a
toEnumDef :: (Enum a, Bounded a) => a -> Int -> a
toEnumNote :: (Partial, Enum a, Bounded a) => String -> Int -> a
toEnumSafe :: (Enum a, Bounded a) => Int -> a
succMay :: (Enum a, Eq a, Bounded a) => a -> Maybe a
succDef :: (Enum a, Eq a, Bounded a) => a -> a -> a
succNote :: (Partial, Enum a, Eq a, Bounded a) => String -> a -> a
succSafe :: (Enum a, Eq a, Bounded a) => a -> a
predMay :: (Enum a, Eq a, Bounded a) => a -> Maybe a
predDef :: (Enum a, Eq a, Bounded a) => a -> a -> a
predNote :: (Partial, Enum a, Eq a, Bounded a) => String -> a -> a
predSafe :: (Enum a, Eq a, Bounded a) => a -> a
indexMay :: Ix a => (a, a) -> a -> Maybe Int
indexDef :: Ix a => Int -> (a, a) -> a -> Int
indexNote :: (Partial, Ix a) => String -> (a, a) -> a -> Int
foldl1Def' :: a -> (a -> a -> a) -> [a] -> a

-- | Substitute various time-related information for each %-code in the
--   string, as per formatCharacter.
--   
--   The general form is
--   %<modifier><width><alternate><specifier>,
--   where <modifier>, <width>, and
--   <alternate> are optional.
--   
--   
<modifier>
--   
--   glibc-style modifiers can be used before the specifier (here marked as
--   z):
--   
--   
--   
- %-z no padding
--   
- %_z pad with spaces
--   
- %0z pad with zeros
--   
- %^z convert to upper case
--   
- %#z convert to lower case (consistently, unlike
--   glibc)
--   
--   
--   
<width>
--   
--   Width digits can also be used after any modifiers and before the
--   specifier (here marked as z), for example:
--   
--   
--   
- %4z pad to 4 characters (with default padding
--   character)
--   
- %_12z pad with spaces to 12 characters
--   
--   
--   
<alternate>
--   
--   An optional E character indicates an alternate formatting.
--   Currently this only affects %Z and %z.
--   
--   
--   
- %Ez alternate formatting
--   
--   
--   
<specifier>
--   
--   For all types (note these three are done by formatTime, not by
--   formatCharacter):
--   
--   
--   
- %% %
--   
- %t tab
--   
- %n newline
--   
--   
--   
TimeZone
--   
--   For TimeZone (and ZonedTime and UTCTime):
--   
--   
--   
- %z timezone offset in the format
--   ±HHMM
--   
- %Ez timezone offset in the format
--   ±HH:MM
--   
- %Z timezone name (or else offset in the format
--   ±HHMM)
--   
- %EZ timezone name (or else offset in the format
--   ±HH:MM)
--   
--   
--   
LocalTime
--   
--   For LocalTime (and ZonedTime and UTCTime
--   and UniversalTime):
--   
--   
--   
- %c as dateTimeFmt locale (e.g.
--   %a %b %e %H:%M:%S %Z %Y)
--   
--   
--   
TimeOfDay
--   
--   For TimeOfDay (and LocalTime and ZonedTime
--   and UTCTime and UniversalTime):
--   
--   
--   
- %R same as %H:%M
--   
- %T same as %H:%M:%S
--   
- %X as timeFmt locale (e.g.
--   %H:%M:%S)
--   
- %r as time12Fmt locale (e.g.
--   %I:%M:%S %p)
--   
- %P day-half of day from (amPm
--   locale), converted to lowercase, am,
--   pm
--   
- %p day-half of day from (amPm
--   locale), AM, PM
--   
- %H hour of day (24-hour), 0-padded to two chars,
--   00 - 23
--   
- %k hour of day (24-hour), space-padded to two
--   chars,  0 - 23
--   
- %I hour of day-half (12-hour), 0-padded to two
--   chars, 01 - 12
--   
- %l hour of day-half (12-hour), space-padded to two
--   chars,  1 - 12
--   
- %M minute of hour, 0-padded to two chars,
--   00 - 59
--   
- %S second of minute (without decimal part),
--   0-padded to two chars, 00 - 60
--   
- %q picosecond of second, 0-padded to twelve chars,
--   000000000000 - 999999999999.
--   
- %Q decimal point and fraction of second, up to 12
--   second decimals, without trailing zeros. For a whole number of
--   seconds, %Q omits the decimal point unless padding is
--   specified.
--   
--   
--   
UTCTime and ZonedTime
--   
--   For UTCTime and ZonedTime:
--   
--   
--   
- %s number of whole seconds since the Unix epoch.
--   For times before the Unix epoch, this is a negative number. Note that
--   in %s.%q and %s%Q the decimals are positive, not
--   negative. For example, 0.9 seconds before the Unix epoch is formatted
--   as -1.1 with %s%Q.
--   
--   
--   
DayOfWeek
--   
--   For DayOfWeek (and Day and LocalTime and
--   ZonedTime and UTCTime and UniversalTime):
--   
--   
--   
- %u day of week number for Week Date format,
--   1 (= Monday) - 7 (= Sunday)
--   
- %w day of week number, 0 (= Sunday) -
--   6 (= Saturday)
--   
- %a day of week, short form (snd from
--   wDays locale), Sun - Sat
--   
- %A day of week, long form (fst from
--   wDays locale), Sunday -
--   Saturday
--   
--   
--   
Month
--   
--   For Month (and Day and LocalTime and
--   ZonedTime and UTCTime and UniversalTime):
--   
--   
--   
- %Y year, no padding. Note %0Y and
--   %_Y pad to four chars
--   
- %y year of century, 0-padded to two chars,
--   00 - 99
--   
- %C century, no padding. Note %0C and
--   %_C pad to two chars
--   
- %B month name, long form (fst from
--   months locale), January -
--   December
--   
- %b, %h month name, short form (snd
--   from months locale), Jan - Dec
--   
- %m month of year, 0-padded to two chars,
--   01 - 12
--   
--   
--   
Day
--   
--   For Day (and LocalTime and ZonedTime and
--   UTCTime and UniversalTime):
--   
--   
--   
- %D same as %m/%d/%y
--   
- %F same as %Y-%m-%d
--   
- %x as dateFmt locale (e.g.
--   %m/%d/%y)
--   
- %d day of month, 0-padded to two chars,
--   01 - 31
--   
- %e day of month, space-padded to two chars, 
--   1 - 31
--   
- %j day of year, 0-padded to three chars,
--   001 - 366
--   
- %f century for Week Date format, no padding. Note
--   %0f and %_f pad to two chars
--   
- %V week of year for Week Date format, 0-padded to
--   two chars, 01 - 53
--   
- %U week of year where weeks start on Sunday (as
--   sundayStartWeek), 0-padded to two chars, 00 -
--   53
--   
- %W week of year where weeks start on Monday (as
--   mondayStartWeek), 0-padded to two chars, 00 -
--   53
--   
--   
--   
Duration types
--   
--   The specifiers for DiffTime, NominalDiffTime,
--   CalendarDiffDays, and CalendarDiffTime are
--   semantically separate from the other types. Specifiers on negative
--   time differences will generally be negative (think rem rather
--   than mod).
--   
--   
NominalDiffTime and DiffTime
--   
--   Note that a "minute" of DiffTime is simply 60 SI seconds,
--   rather than a minute of civil time. Use NominalDiffTime to
--   work with civil time, ignoring any leap seconds.
--   
--   For NominalDiffTime and DiffTime:
--   
--   
--   
- %w total whole weeks
--   
- %d total whole days
--   
- %D whole days of week
--   
- %h total whole hours
--   
- %H whole hours of day
--   
- %m total whole minutes
--   
- %M whole minutes of hour
--   
- %s total whole seconds
--   
- %Es total seconds, with decimal point and up to
--   <width> (default 12) decimal places, without trailing zeros. For
--   a whole number of seconds, %Es omits the decimal point unless
--   padding is specified.
--   
- %0Es total seconds, with decimal point and
--   <width> (default 12) decimal places.
--   
- %S whole seconds of minute
--   
- %ES seconds of minute, with decimal point and up
--   to <width> (default 12) decimal places, without trailing zeros.
--   For a whole number of seconds, %ES omits the decimal point
--   unless padding is specified.
--   
- %0ES seconds of minute as two digits, with decimal
--   point and <width> (default 12) decimal places.
--   
--   
--   
CalendarDiffDays
--   
--   For CalendarDiffDays (and CalendarDiffTime):
--   
--   
--   
- %y total years
--   
- %b total months
--   
- %B months of year
--   
- %w total weeks, not including months
--   
- %d total days, not including months
--   
- %D days of week
--   
--   
--   
CalendarDiffTime
--   
--   For CalendarDiffTime:
--   
--   
--   
- %h total hours, not including months
--   
- %H hours of day
--   
- %m total minutes, not including months
--   
- %M minutes of hour
--   
- %s total whole seconds, not including months
--   
- %Es total seconds, not including months, with
--   decimal point and up to <width> (default 12) decimal places,
--   without trailing zeros. For a whole number of seconds, %Es
--   omits the decimal point unless padding is specified.
--   
- %0Es total seconds, not including months, with
--   decimal point and <width> (default 12) decimal places.
--   
- %S whole seconds of minute
--   
- %ES seconds of minute, with decimal point and up
--   to <width> (default 12) decimal places, without trailing zeros.
--   For a whole number of seconds, %ES omits the decimal point
--   unless padding is specified.
--   
- %0ES seconds of minute as two digits, with decimal
--   point and <width> (default 12) decimal places.
--   
formatTime :: FormatTime t => TimeLocale -> String -> t -> String

-- | Convert from proleptic Gregorian calendar. Invalid values will be
--   clipped to the correct range, month first, then day.
fromGregorian :: Year -> MonthOfYear -> DayOfMonth -> Day
calendarDay :: CalendarDiffDays
calendarWeek :: CalendarDiffDays
calendarMonth :: CalendarDiffDays
calendarYear :: CalendarDiffDays

-- | Scale by a factor. Note that scaleCalendarDiffDays (-1) will
--   not perfectly invert a duration, due to variable month lengths.
scaleCalendarDiffDays :: Integer -> CalendarDiffDays -> CalendarDiffDays
addDays :: Integer -> Day -> Day
diffDays :: Day -> Day -> Integer

-- | A list of all the days in this period.
periodAllDays :: DayPeriod p => p -> [Day]

-- | The number of days in this period.
periodLength :: DayPeriod p => p -> Int

-- | Get the period this day is in, with the 1-based day number within the
--   period.
--   
--   
--   periodFromDay (periodFirstDay p) = (p,1)
--   
periodFromDay :: DayPeriod p => Day -> (p, Int)

-- | Inverse of periodFromDay.
periodToDay :: DayPeriod p => p -> Int -> Day

-- | Validating inverse of periodFromDay.
periodToDayValid :: DayPeriod p => p -> Int -> Maybe Day

-- | Is this year a leap year according to the proleptic Gregorian
--   calendar?
isLeapYear :: Year -> Bool

-- | Convert to proleptic Gregorian calendar.
toGregorian :: Day -> (Year, MonthOfYear, DayOfMonth)

-- | Convert from proleptic Gregorian calendar. Invalid values will return
--   Nothing
fromGregorianValid :: Year -> MonthOfYear -> DayOfMonth -> Maybe Day

-- | Show in ISO 8601 format (yyyy-mm-dd)
showGregorian :: Day -> String

-- | The number of days in a given month according to the proleptic
--   Gregorian calendar.
gregorianMonthLength :: Year -> MonthOfYear -> DayOfMonth

-- | Add months, with days past the last day of the month clipped to the
--   last day. For instance, 2005-01-30 + 1 month = 2005-02-28.
addGregorianMonthsClip :: Integer -> Day -> Day

-- | Add months, with days past the last day of the month rolling over to
--   the next month. For instance, 2005-01-30 + 1 month = 2005-03-02.
addGregorianMonthsRollOver :: Integer -> Day -> Day

-- | Add years, matching month and day, with Feb 29th clipped to Feb 28th
--   if necessary. For instance, 2004-02-29 + 2 years = 2006-02-28.
addGregorianYearsClip :: Integer -> Day -> Day

-- | Add years, matching month and day, with Feb 29th rolled over to Mar
--   1st if necessary. For instance, 2004-02-29 + 2 years = 2006-03-01.
addGregorianYearsRollOver :: Integer -> Day -> Day

-- | Add months (clipped to last day), then add days
addGregorianDurationClip :: CalendarDiffDays -> Day -> Day

-- | Add months (rolling over to next month), then add days
addGregorianDurationRollOver :: CalendarDiffDays -> Day -> Day

-- | Calendrical difference, with as many whole months as possible
diffGregorianDurationClip :: Day -> Day -> CalendarDiffDays

-- | Calendrical difference, with as many whole months as possible. Same as
--   diffGregorianDurationClip for positive durations.
diffGregorianDurationRollOver :: Day -> Day -> CalendarDiffDays
dayOfWeek :: Day -> DayOfWeek

-- | dayOfWeekDiff a b = a - b in range 0 to 6. The number of days
--   from b to the next a.
dayOfWeekDiff :: DayOfWeek -> DayOfWeek -> Int

-- | The first day-of-week on or after some day
firstDayOfWeekOnAfter :: DayOfWeek -> Day -> Day

-- | Returns a week containing the given Day where the first day is
--   the DayOfWeek specified.
--   
--   Examples:
--   
--   
--   >>> weekAllDays Sunday (YearMonthDay 2022 02 21)
--   [YearMonthDay 2022 2 20 .. YearMonthDay 2022 2 26]
--   
--   
--   
--   >>> weekAllDays Monday (YearMonthDay 2022 02 21)
--   [YearMonthDay 2022 2 21 .. YearMonthDay 2022 2 27]
--   
--   
--   
--   >>> weekAllDays Tuesday (YearMonthDay 2022 02 21)
--   [YearMonthDay 2022 2 15 .. YearMonthDay 2022 2 21]
--   
weekAllDays :: DayOfWeek -> Day -> [Day]

-- | Returns the first day of a week containing the given Day.
--   
--   Examples:
--   
--   
--   >>> weekFirstDay Sunday (YearMonthDay 2022 02 21)
--   YearMonthDay 2022 2 20
--   
--   
--   
--   >>> weekFirstDay Monday (YearMonthDay 2022 02 21)
--   YearMonthDay 2022 2 21
--   
--   
--   
--   >>> weekFirstDay Tuesday (YearMonthDay 2022 02 21)
--   YearMonthDay 2022 2 15
--   
weekFirstDay :: DayOfWeek -> Day -> Day

-- | Returns the last day of a week containing the given Day.
--   
--   Examples:
--   
--   
--   >>> weekLastDay Sunday (YearMonthDay 2022 02 21)
--   YearMonthDay 2022 2 26
--   
--   
--   
--   >>> weekLastDay Monday (YearMonthDay 2022 02 21)
--   YearMonthDay 2022 2 27
--   
--   
--   
--   >>> weekLastDay Tuesday (YearMonthDay 2022 02 21)
--   YearMonthDay 2022 2 21
--   
weekLastDay :: DayOfWeek -> Day -> Day

-- | Create a DiffTime which represents an integral number of
--   seconds.
secondsToDiffTime :: Integer -> DiffTime

-- | Create a DiffTime from a number of picoseconds.
picosecondsToDiffTime :: Integer -> DiffTime

-- | Get the number of picoseconds in a DiffTime.
diffTimeToPicoseconds :: DiffTime -> Integer

-- | Create a NominalDiffTime from a number of seconds.
secondsToNominalDiffTime :: Pico -> NominalDiffTime

-- | Get the seconds in a NominalDiffTime.
nominalDiffTimeToSeconds :: NominalDiffTime -> Pico

-- | One day in NominalDiffTime.
nominalDay :: NominalDiffTime

-- | The resolution of getSystemTime, getCurrentTime,
--   getPOSIXTime. On UNIX systems this uses
--   clock_getres, which may be wrong on WSL2.
getTime_resolution :: DiffTime

-- | Get the current UTCTime from the system clock.
getCurrentTime :: IO UTCTime

-- | addUTCTime a b = a + b
addUTCTime :: NominalDiffTime -> UTCTime -> UTCTime

-- | diffUTCTime a b = a - b
diffUTCTime :: UTCTime -> UTCTime -> NominalDiffTime
calendarTimeDays :: CalendarDiffDays -> CalendarDiffTime
calendarTimeTime :: NominalDiffTime -> CalendarDiffTime

-- | Scale by a factor. Note that scaleCalendarDiffTime (-1) will
--   not perfectly invert a duration, due to variable month lengths.
scaleCalendarDiffTime :: Integer -> CalendarDiffTime -> CalendarDiffTime

-- | Create a nameless non-summer timezone for this number of minutes.
minutesToTimeZone :: Int -> TimeZone

-- | Create a nameless non-summer timezone for this number of hours.
hoursToTimeZone :: Int -> TimeZone

-- | Text representing the offset of this timezone, such as "-0800" or
--   "+0400" (like %z in formatTime), with arbitrary padding.
timeZoneOffsetString' :: Maybe Char -> TimeZone -> String

-- | Text representing the offset of this timezone, such as "-0800" or
--   "+0400" (like %z in formatTime).
timeZoneOffsetString :: TimeZone -> String

-- | The UTC time zone.
utc :: TimeZone

-- | Get the configured time-zone for a given time (varying as per
--   summertime adjustments).
--   
--   On Unix systems the output of this function depends on:
--   
--   
--   
- The value of TZ environment variable (if set)
--   
- The system time zone (usually configured by
--   /etc/localtime symlink)
--   
--   
--   For details see tzset(3) and localtime(3).
--   
--   Example:
--   
--   
--   > let t = UTCTime (fromGregorian 2021 7 1) 0
--   > getTimeZone t
--   CEST
--   > setEnv "TZ" "America/New_York" >> getTimeZone t
--   EDT
--   > setEnv "TZ" "Europe/Berlin" >> getTimeZone t
--   CEST
--   
--   
--   On Windows systems the output of this function depends on:
--   
--   
--   
- The value of TZ environment variable (if set). See
--   here for how Windows interprets this variable.
--   
- The system time zone, configured in Settings
--   
getTimeZone :: UTCTime -> IO TimeZone

-- | Get the configured time-zone for the current time.
getCurrentTimeZone :: IO TimeZone

-- | Hour zero
midnight :: TimeOfDay

-- | Hour twelve
midday :: TimeOfDay
makeTimeOfDayValid :: Int -> Int -> Pico -> Maybe TimeOfDay

-- | Convert a period of time into a count of days and a time of day since
--   midnight. The time of day will never have a leap second.
timeToDaysAndTimeOfDay :: NominalDiffTime -> (Integer, TimeOfDay)

-- | Convert a count of days and a time of day since midnight into a period
--   of time.
daysAndTimeOfDayToTime :: Integer -> TimeOfDay -> NominalDiffTime

-- | Convert a time of day in UTC to a time of day in some timezone,
--   together with a day adjustment.
utcToLocalTimeOfDay :: TimeZone -> TimeOfDay -> (Integer, TimeOfDay)

-- | Convert a time of day in some timezone to a time of day in UTC,
--   together with a day adjustment.
localToUTCTimeOfDay :: TimeZone -> TimeOfDay -> (Integer, TimeOfDay)

-- | Get the time of day given a time since midnight. Time more than 24h
--   will be converted to leap-seconds.
timeToTimeOfDay :: DiffTime -> TimeOfDay

-- | Same as timeToTimeOfDay.
pastMidnight :: DiffTime -> TimeOfDay

-- | Get the time since midnight for a given time of day.
timeOfDayToTime :: TimeOfDay -> DiffTime

-- | Same as timeOfDayToTime.
sinceMidnight :: TimeOfDay -> DiffTime

-- | Get the time of day given the fraction of a day since midnight.
dayFractionToTimeOfDay :: Rational -> TimeOfDay

-- | Get the fraction of a day since midnight given a time of day.
timeOfDayToDayFraction :: TimeOfDay -> Rational

-- | addLocalTime a b = a + b
addLocalTime :: NominalDiffTime -> LocalTime -> LocalTime

-- | diffLocalTime a b = a - b
diffLocalTime :: LocalTime -> LocalTime -> NominalDiffTime

-- | Get the local time of a UTC time in a time zone.
utcToLocalTime :: TimeZone -> UTCTime -> LocalTime

-- | Get the UTC time of a local time in a time zone.
localTimeToUTC :: TimeZone -> LocalTime -> UTCTime

-- | Get the local time of a UT1 time on a particular meridian (in degrees,
--   positive is East).
ut1ToLocalTime :: Rational -> UniversalTime -> LocalTime

-- | Get the UT1 time of a local time on a particular meridian (in degrees,
--   positive is East).
localTimeToUT1 :: Rational -> LocalTime -> UniversalTime

-- | Locale representing American usage.
--   
--   knownTimeZones contains only the ten time-zones mentioned in
--   RFC 822 sec. 5: "UT", "GMT", "EST", "EDT", "CST", "CDT", "MST", "MDT",
--   "PST", "PDT". Note that the parsing functions will regardless parse
--   "UTC", single-letter military time-zones, and +HHMM format.
defaultTimeLocale :: TimeLocale

-- | Construct format string according to ISO-8601.
--   
--   The Maybe String argument allows to supply an optional time
--   specification. E.g.:
--   
--   
--   iso8601DateFormat Nothing            == "%Y-%m-%d"           -- i.e. YYYY-MM-DD
--   iso8601DateFormat (Just "%H:%M:%S")  == "%Y-%m-%dT%H:%M:%S"  -- i.e. YYYY-MM-DDTHH:MM:SS
--   
iso8601DateFormat :: Maybe String -> String

-- | Format string according to RFC822.
rfc822DateFormat :: String
utcToZonedTime :: TimeZone -> UTCTime -> ZonedTime
zonedTimeToUTC :: ZonedTime -> UTCTime
getZonedTime :: IO ZonedTime
utcToLocalZonedTime :: UTCTime -> IO ZonedTime

-- | Parses a time value given a format string. Missing information will be
--   derived from 1970-01-01 00:00 UTC (which was a Thursday). Supports the
--   same %-codes as formatTime, including %-,
--   %_ and %0 modifiers, however padding widths are not
--   supported. Case is not significant in the input string. Some
--   variations in the input are accepted:
--   
--   
--   
- %z %Ez accepts any of ±HHMM or
--   ±HH:MM.
--   
- %Z %EZ accepts any string of letters, or
--   any of the formats accepted by %z.
--   
- %0Y accepts exactly four digits.
--   
- %0G accepts exactly four digits.
--   
- %0C accepts exactly two digits.
--   
- %0f accepts exactly two digits.
--   
--   
--   For example, to parse a date in YYYY-MM-DD format, while allowing the
--   month and date to have optional leading zeros (notice the -
--   modifier used for %m and %d):
--   
--   
--   Prelude Data.Time> parseTimeM True defaultTimeLocale "%Y-%-m-%-d" "2010-3-04" :: Maybe Day
--   Just 2010-03-04
--   
parseTimeM :: (MonadFail m, ParseTime t) => Bool -> TimeLocale -> String -> String -> m t

-- | Parses a time value given a list of pairs of format and input.
--   Resulting value is constructed from all provided specifiers.
parseTimeMultipleM :: (MonadFail m, ParseTime t) => Bool -> TimeLocale -> [(String, String)] -> m t

-- | Parse a time value given a format string. Fails if the input could not
--   be parsed using the given format. See parseTimeM for details.
parseTimeOrError :: ParseTime t => Bool -> TimeLocale -> String -> String -> t

-- | Parse a time value given a format string. See parseTimeM for
--   details.
readSTime :: ParseTime t => Bool -> TimeLocale -> String -> ReadS t

-- | Parse a time value given a format string. See parseTimeM for
--   details.
readPTime :: ParseTime t => Bool -> TimeLocale -> String -> ReadP t

-- | Parse hledger CLI options from these command line arguments and add-on
--   command names, or raise any error.
argsToCliOpts :: [String] -> [String] -> IO CliOpts

-- | Common help flags: --help, --debug, --version...
helpflags :: [Flag RawOpts]

-- | A hidden flag just for the hledger executable.
detailedversionflag :: Flag RawOpts

-- | Flags for selecting flat/tree mode, used for reports organised by
--   account. With a True argument, shows some extra help about
--   inclusive/exclusive amounts.
flattreeflags :: Bool -> [Flag RawOpts]

-- | Common flags that are accepted but not shown in --help, such as
--   --effective, --aux-date.
hiddenflags :: [Flag RawOpts]

-- | Common input-related flags: --file, --rules-file, --alias...
inputflags :: [Flag RawOpts]

-- | Common report-related flags: --period, --cost, etc.
reportflags :: [Flag RawOpts]

-- | Common output-related flags: --output-file, --output-format...
outputFormatFlag :: [String] -> Flag RawOpts
outputFileFlag :: Flag RawOpts
generalflagsgroup1 :: (String, [Flag RawOpts])
generalflagsgroup2 :: (String, [Flag RawOpts])
generalflagsgroup3 :: (String, [Flag RawOpts])

-- | An empty cmdargs mode to use as a template. Modes describe the
--   top-level command, ie the program, or a subcommand, telling cmdargs
--   how to parse a command line and how to generate the command's usage
--   text.
defMode :: Mode RawOpts

-- | A cmdargs mode suitable for a hledger built-in command with the given
--   names (primary name + optional aliases). The usage message shows
--   [QUERY] as argument.
defCommandMode :: [Name] -> Mode RawOpts

-- | A cmdargs mode representing the hledger add-on command with the given
--   name, providing hledger's common inputreportinghelp flags. Just
--   used when invoking addons.
addonCommandMode :: Name -> Mode RawOpts

-- | Build a cmdarg mode for a hledger command, from a help template and
--   flag/argument specifications. Reduces boilerplate a little, though the
--   complicated cmdargs flag and argument specs are still required.
hledgerCommandMode :: CommandDoc -> [Flag RawOpts] -> [(String, [Flag RawOpts])] -> [Flag RawOpts] -> ([Arg RawOpts], Maybe (Arg RawOpts)) -> Mode RawOpts
argsFlag :: FlagHelp -> Arg RawOpts

-- | Get a mode's usage message as a nicely wrapped string.
showModeUsage :: Mode a -> String

-- | Add command aliases to the command's help string.
withAliases :: String -> [String] -> String

-- | Get all sorted unique filenames in the current user's PATH. We do not
--   currently filter out non-file objects or files without execute
--   permission.
likelyExecutablesInPath :: IO [String]

-- | Get the sorted unique filenames of all hledger-* executables in the
--   current user's PATH. These are files in any of the PATH directories,
--   named hledger-*, with either no extension (and no periods in the name)
--   or one of the addonExtensions. We do not currently filter out non-file
--   objects or files without execute permission.
hledgerExecutablesInPath :: IO [String]

-- | Convert an argument-less --debug flag to --debug=1 in the given
--   arguments list. Used by hledgeruiweb to make their command line
--   parsing easier somehow.
ensureDebugHasArg :: (Eq (t Char), IsString (t Char), Foldable t) => [t Char] -> [t Char]
defcliopts :: CliOpts
getHledgerCliOpts :: Mode RawOpts -> IO CliOpts

-- | A helper for addon commands: this parses options and arguments from
--   the current command line using the given hledger-style cmdargs mode,
--   and returns a CliOpts. Or, with --help or -h present, it prints long
--   or short help, and exits the program. When --debug is present, also
--   prints some debug output. Note this is not used by the main hledger
--   executable.
--   
--   The help texts are generated from the mode. Long help includes the
--   full usage description generated by cmdargs (including all supported
--   options), framed by whatever pre- and postamble text the mode
--   specifies. It's intended that this forms a complete help document or
--   manual.
--   
--   Short help is a truncated version of the above: the preamble and the
--   first part of the usage, up to the first line containing "flags:"
--   (normally this marks the start of the common hledger flags); plus a
--   mention of --help and the (presumed supported) common hledger options
--   not displayed.
--   
--   Tips: Empty lines in the pre/postamble are removed by cmdargs; add a
--   space character to preserve them.
getHledgerCliOpts' :: Mode RawOpts -> [String] -> IO CliOpts

-- | Parse raw option string values to the desired final data types. Any
--   relative smart dates will be converted to fixed dates based on today's
--   date. Parsing failures will raise an error. Also records the terminal
--   width, if supported.
rawOptsToCliOpts :: RawOpts -> IO CliOpts

-- | All the output formats known by any command, for outputFormatFromOpts.
--   To automatically infer it from -o/--output-file, it needs to be listed
--   here.
outputFormats :: [String]
defaultOutputFormat :: String

-- | Get the (tilde-expanded, absolute) journal file path from 1. options,
--   2. an environment variable, or 3. the default. Actually, returns one
--   or more file paths. There will be more than one if multiple -f options
--   were provided. File paths can have a READER: prefix naming a
--   reader/data format.
journalFilePathFromOpts :: CliOpts -> IO [String]

-- | Get the (tilde-expanded) rules file path from options, if any.
rulesFilePathFromOpts :: CliOpts -> IO (Maybe FilePath)

-- | Get the expanded, absolute output file path specified by an
--   -o/--output-file options, or nothing, meaning stdout.
outputFileFromOpts :: CliOpts -> IO (Maybe FilePath)

-- | Get the output format from the --output-format option, otherwise from
--   a recognised file extension in the --output-file option, otherwise the
--   default (txt).
outputFormatFromOpts :: CliOpts -> String

-- | Default width for hledger console output, when not otherwise
--   specified.
defaultWidth :: Int

-- | Replace any numeric flags (eg -2) with their long form (--depth 2), as
--   I'm guessing cmdargs doesn't support this directly.
replaceNumericFlags :: [String] -> [String]

-- | Get the width in characters to use for the register command's console
--   output, and also the description column width if specified (following
--   the main width, comma-separated). The widths will be as follows: 
--   no --width flag - overall width is the available width (COLUMNS, or
--   posix terminal width, or 80); description width is unspecified (auto)
--   --width W - overall width is W, description width is auto --width W,D
--   - overall width is W, description width is D  Will raise a parse
--   error for a malformed --width argument.
registerWidthsFromOpts :: CliOpts -> (Int, Maybe Int)

-- | Get the sorted unique canonical names of hledger addon commands found
--   in the current user's PATH. These are used in command line parsing and
--   to display the commands list.
--   
--   Canonical addon names are the filenames of hledger-* executables in
--   PATH, without the "hledger-" prefix, and without the file extension
--   except when it's needed for disambiguation (see below).
--   
--   When there are exactly two versions of an executable (same base name,
--   different extensions) that look like a source and compiled pair (one
--   has .exe, .com, or no extension), the source version will be excluded
--   (even if it happens to be newer). When there are three or more
--   versions (or two versions that don't look like a source/compiled
--   pair), they are all included, with file extensions intact.
hledgerAddons :: IO [String]

-- | Get the most appropriate documentation topic for a mode. Currently,
--   that is either the hledger, hledger-ui or hledger-web manual.
topicForMode :: Mode a -> Topic

-- | The test command, which runs the hledger and hledger-lib packages'
--   unit tests. This command also accepts tasty test runner options,
--   written after a -- (double hyphen).
--   
--   Unlike most hledger commands, this one does not read the user's
--   journal. A Journal argument remains in the type signature, but
--   it should not be used (and would raise an error).
testcmd :: CliOpts -> Journal -> IO ()

-- | The cmdargs subcommand mode (for command-line parsing) and IO action
--   (for doing the command's work) for each builtin command. Command
--   actions take parsed CLI options and a (lazy) finalised journal.
builtinCommands :: [(Mode RawOpts, CliOpts -> Journal -> IO ())]

-- | All names and aliases of the builtin commands.
builtinCommandNames :: [String]

-- | Look up a builtin command's mode and action by exact command name or
--   alias.
findBuiltinCommand :: String -> Maybe (Mode RawOpts, CliOpts -> Journal -> IO ())

-- | Canonical names of the known addon commands which have a slot in the
--   commands list, in alphabetical order.
knownAddonCommands :: [String]

-- | Canonical names of all commands which have a slot in the commands
--   list, in alphabetical order. These include the builtin commands and
--   the known addon commands.
knownCommands :: [String]

-- | Print the commands list, with a pager if appropriate, customising the
--   commandsList template above with the given version string and the
--   installed addons. Uninstalled known addons will be removed from the
--   list, installed known addons will have the + prefix removed, and
--   installed unknown addons will be added under Misc.
printCommandsList :: String -> [String] -> IO ()
tests_Hledger_Cli :: TestTree
tests_Cli_Utils :: TestTree

-- | Command line options for this command.
accountsmode :: Mode RawOpts

-- | The accounts command.
accounts :: CliOpts -> Journal -> IO ()
activitymode :: Mode RawOpts
addmode :: Mode RawOpts

-- | Append a string, typically one or more transactions, to a journal
--   file, or if the file is "-", dump it to stdout. Tries to avoid excess
--   whitespace.
--   
--   XXX This writes unix line endings (n), some at least, even if the file
--   uses dos line endings (rn), which could leave mixed line endings in
--   the file. See also writeFileWithBackupIfChanged.
appendToJournalFileOrStdout :: FilePath -> Text -> IO ()

-- | Append this transaction to the journal's file and transaction list.
journalAddTransaction :: Journal -> CliOpts -> Transaction -> IO Journal

-- | Render a register report as plain text suitable for console output.
postingsReportAsText :: CliOpts -> PostingsReport -> Text
journalSimilarTransaction :: CliOpts -> Journal -> Text -> Maybe Transaction
aregistermode :: Mode RawOpts

-- | Print an account register report for a specified account.
aregister :: CliOpts -> Journal -> IO ()
tests_Aregister :: TestTree

-- | Command line options for this command.
balancemode :: Mode RawOpts

-- | Render a single-column balance report as plain text.
balanceReportAsText :: ReportOpts -> BalanceReport -> Builder

-- | Render a single-column balance report as CSV.
balanceReportAsCsv :: ReportOpts -> BalanceReport -> CSV

-- | Render one balance report line item as plain text suitable for console
--   output (or whatever string format is specified). Note, prices will not
--   be rendered, and differently-priced quantities of the same commodity
--   will appear merged. The output will be one or more lines depending on
--   the format and number of commodities.
balanceReportItemAsText :: ReportOpts -> BalanceReportItem -> (Builder, [Int])
multiBalanceRowAsCsvText :: ReportOpts -> [DateSpan] -> PeriodicReportRow a MixedAmount -> [[Text]]
multiBalanceRowAsTableText :: ReportOpts -> PeriodicReportRow a MixedAmount -> [[WideBuilder]]

-- | Render a multi-column balance report as plain text suitable for
--   console output.
multiBalanceReportAsText :: ReportOpts -> MultiBalanceReport -> Text

-- | Render a multi-column balance report as CSV. The CSV will always
--   include the initial headings row, and will include the final totals
--   row unless --no-total is set.
multiBalanceReportAsCsv :: ReportOpts -> MultiBalanceReport -> CSV

-- | Render a multi-column balance report as HTML.
multiBalanceReportAsHtml :: ReportOpts -> MultiBalanceReport -> Html ()

-- | Render the HTML table rows for a MultiBalanceReport. Returns the
--   heading row, 0 or more body rows, and the totals row if enabled.
multiBalanceReportHtmlRows :: ReportOpts -> MultiBalanceReport -> (Html (), [Html ()], [Html ()])

-- | Render one MultiBalanceReport totals row as a HTML table row.
multiBalanceReportHtmlFootRow :: ReportOpts -> [Text] -> Html ()

-- | Build a Table from a multi-column balance report.
balanceReportAsTable :: ReportOpts -> MultiBalanceReport -> Table Text Text WideBuilder
tests_Balance :: TestTree
balancesheetmode :: Mode RawOpts
balancesheet :: CliOpts -> Journal -> IO ()
balancesheetequitymode :: Mode RawOpts
balancesheetequity :: CliOpts -> Journal -> IO ()
cashflowmode :: Mode RawOpts
cashflow :: CliOpts -> Journal -> IO ()
closemode :: Mode RawOpts

-- | Command line options for this command.
codesmode :: Mode RawOpts

-- | The codes command.
codes :: CliOpts -> Journal -> IO ()

-- | Command line options for this command.
commoditiesmode :: Mode RawOpts
commodities :: CliOpts -> Journal -> IO ()

-- | Command line options for this command.
demomode :: Mode RawOpts

-- | The demo command.
demo :: CliOpts -> Journal -> IO ()

-- | Command line options for this command.
descriptionsmode :: Mode RawOpts

-- | The descriptions command.
descriptions :: CliOpts -> Journal -> IO ()

-- | Command line options for this command.
diffmode :: Mode RawOpts
helpmode :: Mode RawOpts

-- | Display the hledger manual in various formats. You can select a docs
--   viewer with one of the `--info`, `--man`, `--pager` flags. Otherwise
--   it will use the first available of: info, man, $PAGER, less, stdout
--   (and always stdout if output is non-interactive).
help' :: CliOpts -> Journal -> IO ()
importmode :: Mode RawOpts
importcmd :: CliOpts -> Journal -> IO ()
incomestatementmode :: Mode RawOpts
incomestatement :: CliOpts -> Journal -> IO ()

-- | Command line options for this command.
notesmode :: Mode RawOpts

-- | The notes command.
notes :: CliOpts -> Journal -> IO ()

-- | Command line options for this command.
payeesmode :: Mode RawOpts

-- | The payees command.
payees :: CliOpts -> Journal -> IO ()
pricesmode :: Mode RawOpts
prices :: CliOpts -> Journal -> IO ()
printmode :: Mode RawOpts

-- | Print journal transactions in standard format.
print' :: CliOpts -> Journal -> IO ()

-- | Replace this transaction's postings with the original postings if any,
--   but keep the current possibly rewritten account names, and the
--   inferred values of any auto postings. This is mainly for showing
--   transactions with the amounts in their original journal format.
transactionWithMostlyOriginalPostings :: Transaction -> Transaction
registermode :: Mode RawOpts

-- | Print a (posting) register report.
register :: CliOpts -> Journal -> IO ()

-- | Render one register report line item as plain text. Layout is like so:
--    width (specified, terminal width, or 80)
--   -------------------- date (10) description account amount (12)
--   balance (12) DDDDDDDDDD dddddddddddddddddddd aaaaaaaaaaaaaaaaaaa
--   AAAAAAAAAAAA AAAAAAAAAAAA  If description's width is specified,
--   account will use the remaining space. Otherwise, description and
--   account divide up the space equally.
--   
--   With a report interval, the layout is like so:  width
--   (specified, terminal width, or 80) -------------------- date (21)
--   account amount (12) balance (12) DDDDDDDDDDDDDDDDDDDDD
--   aaaaaaaaaaaaaaaaaaaaaaaaaaaaa AAAAAAAAAAAA AAAAAAAAAAAA 
--   
--   date and description are shown for the first posting of a transaction
--   only.
--   
--   Returns a string which can be multi-line, eg if the running balance
--   has multiple commodities. Does not yet support formatting control like
--   balance reports.
--   
--   Also returns the natural width (without padding) of the amount and
--   balance fields.
postingsReportItemAsText :: CliOpts -> Int -> Int -> (PostingsReportItem, [WideBuilder], [WideBuilder]) -> Builder
tests_Register :: TestTree
rewritemode :: Mode RawOpts
rewrite :: CliOpts -> Journal -> IO ()
statsmode :: Mode RawOpts

-- | Print various statistics for the journal.
stats :: CliOpts -> Journal -> IO ()

-- | Write some output to stdout or to a file selected by --output-file. If
--   the file exists it will be overwritten. This function operates on Lazy
--   Text values.
writeOutputLazyText :: CliOpts -> Text -> IO ()
tagsmode :: Mode RawOpts
tags :: CliOpts -> Journal -> IO ()

-- | Generate a cmdargs option-parsing mode from a compound balance command
--   specification.
compoundBalanceCommandMode :: CompoundBalanceCommandSpec -> Mode RawOpts

-- | Generate a runnable command from a compound balance command
--   specification.
compoundBalanceCommand :: CompoundBalanceCommandSpec -> CliOpts -> Journal -> IO ()

-- | Standard error message for a bad output format specified with -O/-o.
unsupportedOutputFormatError :: String -> String

-- | Print plain text help for this tool. Takes an optional topic argument
--   for convenience but it is currently ignored.
printHelpForTopic :: Tool -> Maybe Topic -> IO ()

-- | Display a man page for this tool, scrolled to the given topic if
--   provided, using the "man" executable in $PATH. Note when a topic is
--   provided we force man to use the "less" executable in $PATH, ignoring
--   $MANPAGER and $PAGER.
runManForTopic :: Tool -> Maybe Topic -> IO ()

-- | Display an info manual for this topic, opened at the given topic if
--   provided, using the "info" executable in $PATH.
runInfoForTopic :: Tool -> Maybe Topic -> IO ()

-- | Display plain text help for this tool, scrolled to the given topic if
--   provided, using the given pager executable. Note when a topic is
--   provided we ignore the provided pager and use the "less" executable in
--   $PATH.
runPagerForTopic :: Tool -> Maybe Topic -> IO ()

-- | Parse the user's specified journal file(s) as a Journal, maybe apply
--   some transformations according to options, and run a hledger command
--   with it. Or, throw an error.
withJournalDo :: CliOpts -> (Journal -> IO a) -> IO a

-- | Write some output to stdout or to a file selected by --output-file. If
--   the file exists it will be overwritten.
writeOutput :: CliOpts -> String -> IO ()

-- | Apply some extra post-parse transformations to the journal, if enabled
--   by options. These happen after parsing and finalising the journal, but
--   before report calculation. They are, in processing order:
--   
--   
--   
- pivoting account names (--pivot)
--   
- anonymising (--anonymise).
--   
journalTransform :: CliOpts -> Journal -> Journal

-- | Re-read the journal file(s) specified by options, applying any
--   transformations specified by options. Or return an error string. Reads
--   the full journal, without filtering.
journalReload :: CliOpts -> ExceptT String IO Journal

-- | Re-read the option-specified journal file(s), but only if any of them
--   has changed since last read. (If the file is standard input, this will
--   either do nothing or give an error, not tested yet). Returns a journal
--   or error message, and a flag indicating whether it was re-read or not.
--   Like withJournalDo and journalReload, reads the full journal, without
--   filtering.
journalReloadIfChanged :: CliOpts -> Day -> Journal -> ExceptT String IO (Journal, Bool)

-- | Has the specified file changed since the journal was last read ?
--   Typically this is one of the journal's journalFilePaths. These are not
--   always real files, so the file's existence is tested first; for
--   non-files the answer is always no.
journalFileIsNewer :: Journal -> FilePath -> IO Bool

-- | Attempt to open a web browser on the given url, all platforms.
openBrowserOn :: String -> IO ExitCode

-- | Back up this file with a (incrementing) numbered suffix, then
--   overwrite it with this new text, or give an error.
writeFileWithBackup :: FilePath -> String -> IO ()

-- | Back up this file with a (incrementing) numbered suffix then overwrite
--   it with this new text, or give an error, but only if the text is
--   different from the current file contents, and return a flag indicating
--   whether we did anything.
--   
--   The given text should have unix line endings (n); the existing file
--   content will be normalised to unix line endings before comparing the
--   two. If the file is overwritten, the new file will have the current
--   system's native line endings (n on unix, rn on windows). This could be
--   different from the file's previous line endings, if working with a DOS
--   file on unix or vice-versa.
writeFileWithBackupIfChanged :: FilePath -> Text -> IO Bool

-- | Apply the pivot transformation on a journal (replacing account names
--   by a different field's value), if option is present.
pivotByOpts :: CliOpts -> Journal -> Journal

-- | Raise an error, announcing the rename to --obfuscate and its
--   limitations.
anonymiseByOpts :: CliOpts -> Journal -> Journal

-- | Render a PostingsReport or AccountTransactionsReport as
--   Text, determining the appropriate starting widths and increasing as
--   necessary.
postingsOrTransactionsReportAsText :: Bool -> CliOpts -> (Int -> Int -> (a, [WideBuilder], [WideBuilder]) -> Builder) -> (a -> MixedAmount) -> (a -> MixedAmount) -> [a] -> Builder

-- | The "1.32.3" string defined with -D in this package's
--   package.yaml/.cabal file (by Shake setversion), if any. Normally a
--   dotted number string with 1-3 components.
packageversion :: PackageVersion

-- | Just the first 1-2 components of packageversion.
packagemajorversion :: PackageVersion

-- | The name of this package's main executable.
progname :: ProgramName

-- | Given possible git state info from the build directory (or an error
--   message, which is ignored), the name of a program (executable) in the
--   currently building package, and the package's version, make a complete
--   version string. Here is the logic:
--   
--   
--   
- Program name, OS and architecture are always shown.
--   
- The package version is always shown.
--   
- If there is git info at build time, the latest commit hash and
--   commit date are shown, and (TODO, requires githash to use -uno for
--   giDirty): if the working copy has uncommitted changes a + sign is
--   appended.
--   
- (TODO, requires adding --match support to githash: If there are
--   tags matching THISPKG-[0-9]*, the latest one is used to calculate
--   patch level (number of commits since tag), and if non-zero, it and the
--   branch name are shown.)
--   
--   
--   Some example outputs:
--   
--   
--   
- A homebrew binary, not built in git repo: hledger-ui 1.24,
--   mac-aarch64
--   
- A CI release build, built in git repo at release tag: hledger-ui
--   1.24.1-g455b35293-20211210, mac-x86_64
--   
- (TODO) A dev build, built in git repo: hledger-ui
--   1.24.1+1-g4abd8ef10-20211210 (1.24-branch), mac-x86_64
--   
--   
--   This function requires git log to show the default (rfc2822-style)
--   date format, so that must not be overridden by a log.date git config
--   variable.
versionStringWith :: Either String GitInfo -> ProgramName -> PackageVersion -> VersionString
barchar :: Char

-- | Print a bar chart of number of postings per report interval.
activity :: CliOpts -> Journal -> IO ()
showHistogram :: ReportSpec -> Journal -> String
printDayWith :: (PrintfArg t1, PrintfType t2) => (t3 -> t1) -> (DateSpan, t3) -> t2
countBar :: Foldable t => t a -> [Char]
