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.
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.
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.
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.
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.
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.)
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.
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:
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:
Use compareLengthxsn as a safer and faster alternative
to compare (lengthxs) n. Similarly, it's better
to write compareLength xs 10 == LT instead of length xs < 10.
While length would force and traverse
the entire spine of xs (which could even diverge if xs is infinite),
compareLength traverses at most n elements to determine its result.
Computation exitWithcode throws ExitCodecode.
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 exitWithExitSuccess.
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.
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:
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.
Substitute a 'v' format character with the given
default format character in the FieldFormat. A
convenience for user-implemented types, which should
support "%v".
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
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.
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.
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.
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"
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.
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 System.FilePath.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.
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.
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.
System.IO.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]
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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]
System.IO.isFullError
Insufficient resources are available to perform the operation.
UnsupportedOperation
The operating system has no notion of current working 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.
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 process' user. This basically reads the /etc/passwd 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.
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.
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
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.
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.
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.
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.
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.
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.
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]
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.
removeFilefile 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]
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.
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]
System.IO.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]
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.
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]
System.IO.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]
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.
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]
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.
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
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.
Returns width of a character in a monospace font: 0 for a combining
character, 1 for a regular character, 2 for an East Asian wide character.
Ambiguous characters are treated as width 1.
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
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.
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.
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/"
dropExtensions "/directory/path.ext" == "/directory/path"
dropExtensions "file.tar.gz" == "file"
not $ hasExtension $ dropExtensions x
not $ any isExtSeparator $ takeFileName $ dropExtensions x
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:/")
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.
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"
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.
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.
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
If the first list is not finite, the result is the first list.
Performance considerations
This function takes linear time in the number of elements of the
first list. Thus it is better to associate repeated
applications of (++) to the right (which is the default behaviour):
xs ++ (ys ++ zs) or simply xs ++ ys ++ zs, but not (xs ++ ys) ++ zs.
For the same reason GHC.Internal.Data.List.concat=GHC.Internal.Data.List.foldr(++)[]
has linear performance, while GHC.Internal.Data.List.foldl(++)[] is prone
to quadratic slowdown
A variant of <*> with the types of the arguments reversed. It differs from
flip(<*>) in that the effects are resolved in the order the arguments are
presented.
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.
A common use of join is to run an IO computation returned from
an GHC.Conc.STM transaction, since GHC.Conc.STM transactions
can't perform IO directly. Recall that
GHC.Internal.Conc.atomically :: STM a -> IO a
is used to run GHC.Conc.STM transactions atomically. So, by
specializing the types of GHC.Internal.Conc.atomically and join to
GHC.Internal.Conc.atomically :: STM (IO b) -> IO (IO b)
join :: IO (IO b) -> IO b
we can compose them as
join . GHC.Internal.Conc.atomically :: STM (IO b) -> IO b
to run an GHC.Conc.STM transaction and the IO action it
returns.
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.
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.
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.
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.
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
GHC.Control.Exception.mask).
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.
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
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.
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).
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.
labelThread stores a string as identifier for this thread. This
identifier will be used in the debugging output to make distinction of
different threads easier (otherwise you only have the thread state object's
address in the heap). It also emits an event to the RTS eventlog.
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.
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.
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.
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.
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.
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.
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.
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.
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.
A common use of forever is to process input from network sockets,
System.IO.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:
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.
Common uses of guard include conditionally signalling an error in
an error monad and conditionally rejecting the current choice in an
Alternative-based parser.
As an example of signalling 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:
Example1 expression
>>> safeDiv 4 0Nothing
Example1 expression
>>> safeDiv 4 2Just 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 Monaddo-notation:
safeDiv :: Int -> Int -> Maybe Int
safeDiv x y = do
guard (y /= 0)
return (x `div` y)
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.
If we are strict in the value, just as with Data.Function.fix, we do not get termination:
Example1 expression
>>> fixIO (\x -> putStr x >> pure ('x' : x))* hangs forever *
We can tie the knot of a structure within IO using fixIO:
data Node = MkNode Int (IORef Node)
foo :: IO ()
foo = do
p <- fixIO (p -> newIORef (MkNode 0 p))
q <- output p
r <- output q
_ <- output r
pure ()
output :: IORef Node -> IO (IORef Node)
output ref = do
MkNode x p <- readIORef ref
print x
pure p
Example1 expression
>>> foo000
vvalueeither :: (a -> c) -> (b -> c) -> Eitherab -> c
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 EitherStringInt, one using the
Left constructor and another using the Right constructor. Then
we apply "either" the Prelude.length function (if we have a String)
or the "times-two" function (if we have an Int):
Example4 expressions
>>> let s = Left "foo" :: Either String Int>>> let n = Right 3 :: Either String Int>>> either length (*2) s3>>> either length (*2) n6
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:
Example4 expressions
>>> import Control.Monad ( when )>>> let report e = when (isLeft e) $ putStrLn "ERROR">>> report (Right 1)>>> report (Left "parse error")ERROR
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:
Example4 expressions
>>> import Control.Monad ( when )>>> let report e = when (isRight e) $ putStrLn "SUCCESS">>> report (Left "parse error")>>> report (Right 1)SUCCESS
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:
Example2 expressions
>>> let list = [ Left "foo", Right 3, Left "bar", Right 7, Left "baz" ]>>> partitionEithers list(["foo","bar","baz"],[3,7])
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:
Example1 expression
>>> and []True
Example1 expression
>>> and [True]True
Example1 expression
>>> and [False]False
Example1 expression
>>> and [True, True, False]False
Example1 expression
>>> and (False : repeat True) -- Infinite list [False,True,True,True,...False
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.
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
Data.Traversable.mapM.
mapM_ is just like traverse_, but specialised to monadic actions.
The largest element of a non-empty structure with respect to the
given comparison function. Structure order is used as a tie-breaker: if
there are multiple largest elements, the rightmost of them is chosen.
The least element of a non-empty structure with respect to the
given comparison function. Structure order is used as a tie-breaker: if
there are multiple least elements, the leftmost of them is chosen.
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:
Example1 expression
>>> or []False
Example1 expression
>>> or [True]True
Example1 expression
>>> or [False]False
Example1 expression
>>> or [True, True, False]True
Example1 expression
>>> or (True : repeat False) -- Infinite list [True,False,False,False,...True
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 Data.Traversable.sequence.
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.
The catMaybes function takes a list of Maybes and returns
a list of all the Just values.
Examples
Basic usage:
Example1 expression
>>> 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):
Example3 expressions
>>> import GHC.Internal.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]
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.
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:
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:
Example1 expression
>>> maybe False odd (Just 3)True
Example1 expression
>>> maybe False odd NothingFalse
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:
Apply show to a Maybe Int. If we have Just n, we want to show
the underlying Intn. But if we have Nothing, we return the
empty string instead of (for example) "Nothing":
Example2 expressions
>>> maybe "" show (Just 5)"5">>> maybe "" show Nothing""
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.
It is a special case of deleteFirstsBy, which allows the programmer
to supply their own equality test.
Examples
Example1 expression
>>> "Hello World!" \\ "ell W""Hoorld!"
The second list must be finite, but the first may be infinite.
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 (\\).
(\\) == deleteFirstsBy (==)
The second list must be finite, but the first may be infinite.
The dropWhileEnd function drops the largest suffix of a list
in which the given predicate holds for all elements.
Laziness
This function is lazy in spine, but strict in elements,
which makes it different from reverse.dropWhilep.reverse,
which is strict in spine, but lazy in elements. For instance:
Example1 expression
>>> take 1 (dropWhileEnd (< 0) (1 : undefined))[1]
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.
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.
\mathcal{O}(n). 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.
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.
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, all elements are equal to the
first one, and consecutive equal elements of the input end up in the
same element of the output list.
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.
A common idiom to squash repeating elements maphead.group
is better served by
mapData.List.NonEmpty.head.Data.List.NonEmpty.group
because it avoids partial functions.
Examples
Example1 expression
>>> group "Mississippi"["M","i","ss","i","ss","i","pp","i"]
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:
Example1 expression
>>> 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.
\mathcal{O}(n). 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.
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.
Examples
Example1 expression
>>> [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:
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:
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.
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.
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 . linesidempotent:
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.
This function knows too little about the elements to be efficient.
Its asymptotic complexity is
O(n ⋅ d), where d is the number of distinct elements in the list.
If there exists instance Ord a, it's faster to use nubOrd.
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)
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.
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.
The sortBy function is the non-overloaded version of sort.
The argument must be finite.
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.
Examples
Example1 expression
>>> sortBy (\(a,_) (b,_) -> compare a b) [(2, "world"), (4, "!"), (1, "Hello")][(1,"Hello"),(2,"world"),(4,"!")]
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.
\mathcal{O}(\min(m,n)). 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.
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
Laziness
Example1 expression
>>> take 1 (unfoldr (\x -> Just (x, undefined)) 'a')"a"
Examples
Example1 expression
>>> unfoldr (\b -> if b == 0 then Nothing else Just (b, b-1)) 10[10,9,8,7,6,5,4,3,2,1]
Example1 expression
>>> take 10 $ unfoldr (\(x, y) -> Just (x, (y, x + y))) (0, 1)[0,1,1,2,3,5,8,13,21,54]
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.
Examples
Example1 expression
>>> "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:
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.
Examples
Example1 expression
>>> words "Lorem ipsum\ndolor"["Lorem","ipsum","dolor"]
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.
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.
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.
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.
vvaluezipWith4 :: (a -> b -> c -> d -> e) -> [a] -> [b] -> [c] -> [d] -> [e]
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.
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.
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.
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.
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.
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:
Example1 expression
>>> mapAccumL (\a b -> (a + b, a)) 0 [1..10](55,[0,1,3,6,10,15,21,28,36,45])
Example1 expression
>>> mapAccumL (\a b -> (a <> show b, a)) "0" [1..5]("012345",["0","01","012","0123","01234"])
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:
Example1 expression
>>> mapAccumR (\a b -> (a + b, a)) 0 [1..10](55,[54,52,49,45,40,34,27,19,10,0])
Example1 expression
>>> mapAccumR (\a b -> (a <> show b, a)) "0" [1..5]("054321",["05432","0543","054","05","0"])
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.
Example2 expressions
>>> 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.
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.
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 System.IO.Handle using the latin1 encoding will result in an
error.
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 criterion, 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".
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.
Computation hClosehdl 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.
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.
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.
For a readable handle hdl, hIsEOFhdl 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.
On Windows the result of hIsTerminalDevide might be misleading,
because non-native terminals, such as MinTTY used in MSYS 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.
Computation hSeekhdl 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:
GHC.Internal.System.IO.Error.isIllegalOperationError if the Handle is not seekable,
or does not support the requested seek mode.
The action hSetEncodinghdlencoding 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.
If a call to hGetPosnhdl returns a position p,
then computation hSetPosnp sets the position of hdl
to the position it held at the time of the call to hGetPosn.
Computation hTellhdl 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:
GHC.Internal.System.IO.Error.isIllegalOperationError if the Handle is not seekable.
hGetBufhdl 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 System.IO.TextEncoding and NewlineMode
on the Handle, and reads bytes directly.
hGetBufNonBlockinghdl 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.
hGetBufSomehdl 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 System.IO.TextEncoding and
NewlineMode on the Handle, and reads bytes directly.
Computation hGetContentshdl 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 treated like a closed handle, with the
following exceptions:
Characters can be read from hdl by evaluating portions of the
list returned by hGetContentshdl.
If the handle allows for independent reading and writing, as it is
the case for socket handles, writing continues to be possible.
A semi-closed handle becomes closed:
if GHC.Internal.System.IO.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.
Computation hGetLinehdl 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 GHC.Internal.System.IO.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
Example1 expression
>>> withFile "/home/user/foo" ReadMode hGetLine >>= putStrLnthis is the first line of the file :O
Example1 expression
>>> withFile "/home/user/bar" ReadMode (replicateM 3 . hGetLine)["this is the first line","this is the second line","this is the third line"]
hPutBufhdl 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 System.IO.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).
>>> let f = forkIO . hPutStr stdout>>> in do hSetBuffering stdout NoBuffering; f "This is a longer string"; f ":D"; f "Hello Haskell"; pure ()This: HDiesl lao lHoansgkeerl lstring
Example2 expressions
>>> let f = forkIO . hPutStr stdout>>> in do hSetBuffering stdout LineBuffering; f "This is a longer string"; f ":D"; f "Hello Haskell"; pure ()This is a longer string:DHello Haskell
Computation hWaitForInputhdl 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.
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.
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.
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 satisfyp and second element is the remainder of the list:
breakp is equivalent to span (not . p)
and consequently to (takeWhile (not . p) xs, dropWhile (not . p) xs),
even if p is _|_.
This is a partial function, it throws an error on empty lists. Use pattern matching, Data.List.uncons or listToMaybe instead. Consider refactoring to use Data.List.NonEmpty.
\mathcal{O}(1). Extract the first element of a list, which must be non-empty.
To disable the warning about partiality put {-# OPTIONS_GHC -Wno-x-partial -Wno-unrecognised-warning-flags #-}
at the top of the file. To disable it throughout a package put the same
options into ghc-options section of Cabal file. To disable it in GHCi
put :set -Wno-x-partial -Wno-unrecognised-warning-flags into ~/.ghci config file.
See also the migration guide.
Examples
Example1 expression
>>> head [1, 2, 3]1
Example1 expression
>>> head [1..]1
Example1 expression
>>> head []*** Exception: Prelude.head: empty list
This is a partial function, it throws an error on empty lists. Use Data.List.unsnoc instead. Consider refactoring to use Data.List.NonEmpty.
\mathcal{O}(n). Return all the elements of a list except the last one.
The list must be non-empty.
To disable the warning about partiality put
{-# OPTIONS_GHC -Wno-x-partial -Wno-unrecognised-warning-flags #-}
at the top of the file. To disable it throughout a package put the same
options into ghc-options section of Cabal file. To disable it in GHCi
put :set -Wno-x-partial -Wno-unrecognised-warning-flags into ~/.ghci
config file. See also the
migration guide.
Examples
Example1 expression
>>> init [1, 2, 3][1,2]
Example1 expression
>>> init [1][]
Example1 expression
>>> init []*** Exception: Prelude.init: empty list
iteratef x returns an infinite list of repeated applications
of f to x:
iterate f x == [x, f x, f (f x), ...]
Laziness
Note that iterate is lazy, potentially leading to thunk build-up if
the consumer doesn't force each element. See iterate' for a strict
variant of this function.
Example3 expressions
>>> let xs = iterate (\x -> if x == 0 then undefined else x - 1) 2>>> xs[2,1,0,*** Exception: Prelude.undefined>>> length (take 10 xs)10
In xs every element following 0 is bottom, but the list itself is
infinitely long because it is generated without forcing its elements.
Examples
Example1 expression
>>> take 10 $ iterate not True[True,False,True,False,True,False,True,False,True,False]
Example1 expression
>>> take 10 $ iterate (+3) 42[42,45,48,51,54,57,60,63,66,69]
This is a partial function, it throws an error on empty lists. Use Data.List.unsnoc instead. Consider refactoring to use Data.List.NonEmpty.
\mathcal{O}(n). Extract the last element of a list, which must be
finite and non-empty.
To disable the warning about partiality put
{-# OPTIONS_GHC -Wno-x-partial -Wno-unrecognised-warning-flags #-}
at the top of the file. To disable it throughout a package put the same
options into ghc-options section of Cabal file. To disable it in GHCi
put :set -Wno-x-partial -Wno-unrecognised-warning-flags into ~/.ghci
config file. See also the
migration guide.
Examples
Example1 expression
>>> last [1, 2, 3]3
Example1 expression
>>> last [1..]* Hangs forever *
Example1 expression
>>> last []*** Exception: Prelude.last: empty list
replicaten 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.
\mathcal{O}(n). 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
span, applied to a predicate p and a list xs, returns a tuple where
first element is the longest prefix (possibly empty) of xs of elements that
satisfy p and second element is the remainder of the list:
This is a partial function, it throws an error on empty lists. Replace it with drop 1, or use pattern matching or Data.List.uncons instead. Consider refactoring to use Data.List.NonEmpty.
\mathcal{O}(1). Extract the elements after the head of a list, which
must be non-empty.
To disable the warning about partiality put {-# OPTIONS_GHC -Wno-x-partial -Wno-unrecognised-warning-flags #-}
at the top of the file. To disable it throughout a package put the same
options into ghc-options section of Cabal file. To disable it in GHCi
put :set -Wno-x-partial -Wno-unrecognised-warning-flags into ~/.ghci config file.
See also the migration guide.
Examples
Example1 expression
>>> tail [1, 2, 3][2,3]
Example1 expression
>>> tail [1][]
Example1 expression
>>> tail []*** Exception: Prelude.tail: empty list
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.
vvaluezipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
\mathcal{O}(\min(l,m,n)). 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..]
Examples
Example1 expression
>>> zipWith3 (\x y z -> [x, y, z]) "123" "abc" "xyz"["1ax","2by","3cz"]
Example1 expression
>>> zipWith3 (\x y z -> (x * y) + z) [1, 2, 3] [4, 5, 6] [7, 8, 9][11,18,27]
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.
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.
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.
The runtime guarantees that all woken threads complete their readMVar operation.
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
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.
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.
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.
Read a string representation of a character, using Haskell
source-language escape conventions, and convert it to the character
that it encodes. For example:
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.
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.
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
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.
Beware that this function must not be executed concurrently
with getEnv, lookupEnv, getEnvironment and such. One thread
reading environment variables at the same time with another one modifying them
can result in a segfault, see
Setenv is not Thread Safe
for discussion.
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.
Beware that this function must not be executed concurrently
with getEnv, lookupEnv, getEnvironment and such. One thread
reading environment variables at the same time with another one modifying them
can result in a segfault, see
Setenv is not Thread Safe
for discussion.
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, Solaris, 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.
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.
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.
This operation may fail with the same errors as hPutStr and withFile.
Examples
The following example could be more efficently written by acquiring a handle
instead with openFile and using the computations capable of writing to handles
such as hPutStr.
Example2 expressions
>>> let fn = "hello_world">>> in writeFile fn "hello" >> appendFile fn " world!" >> (readFile fn >>= putStrLn)"hello world!"
Example2 expressions
>>> let fn = "foo"; output = readFile' fn >>= putStrLn>>> in output >> appendFile fn (show [1,2,3]) >> outputthis is what's in the filethis is what's in the file[1,2,3]
File name template. If the template is "foo.ext" then
the created file will be "fooXXX.ext" where XXX is some
random number. Note that this should not contain any path
separator characters. On Windows, the template prefix may
be truncated to 3 chars, e.g. "foobar.ext" will be
"fooXXX.ext".
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.
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.
This operation may fail with the same errors, and has the same issues with concurrency, as hPutStr!
Examples
Example1 expression
>>> print [1, 2, 3][1,2,3]
Be careful when using print for outputting strings,
as this will invoke show and cause strings to be printed
with quotation marks and non-ascii symbols escaped.
Example1 expression
>>> print "λ :D""\995 :D"
A program to print the first 8 integers and their
powers of 2 could be written as:
Example1 expression
>>> print [(n, 2^n) | n <- [0..8]][(0,1),(1,2),(2,4),(3,8),(4,16),(5,32),(6,64),(7,128),(8,256)]
Adds a location description and maybe a file path and file handle
to an IOError. If any of the file handle or file path is not given
the corresponding value in the IOError remains unaltered.
The catchIOError function establishes a handler that receives any
IOError raised in the action protected by catchIOError.
An IOError is caught by
the most recent handler established by one of the exception handling
functions. These handlers are
not selective: all IOErrors 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 IOError value and exits the program.
Non-I/O exceptions are not caught by this variant; to catch all
exceptions, use catch from Control.Exception.
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).
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.
Construct an IOError 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.
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.
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.
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.
This function returns True if its argument has one of the
following GeneralCategorys, or False otherwise:
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, e.g., Roman numerals like V,
full-width digits like '1' (aka '65297').
This function returns True if its argument has one of the
following GeneralCategorys, or False otherwise:
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 GeneralCategoryLowercaseLetter.
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).
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".
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 GeneralCategoryUppercaseLetter or TitlecaseLetter.
See isUpperCase for a more intuitive predicate. Note that
unlike isUpperCase, isUpper does select title-case characters such as
'Dž' (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).
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
'Dž' (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).
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.
A helper for addons/scripts: this parses hledger CliOpts from these
command line arguments and add-on command names, roughly how hledger main does.
If option parsing/validating fails, it exits the program with usageError.
Unlike main, this does not read extra args from a config file
or search for addons; to do those things, mimic the code in main for now.
Derive 1. an account tree and 2. each account's total exclusive
and inclusive changes associated with dates from a list of postings and a
function for associating a date to each posting (usually representing the
start dates of report subperiods).
This is the core of the balance command (and of *ledger).
The accounts are returned as a tree.
Convert a list of account names to a tree of Account objects,
with just the account names filled in and an empty balance.
A single root account with the given name is added.
Convert a list of account names to a tree of Account objects,
with just the account names filled in. Each account is given the same
supplied balance.
A single root account with the given name is added.
Derive 1. an account tree and 2. each account's total exclusive and
inclusive changes associated with dates from a list of postings and a
function for associating a date to each posting (usually representing the
start dates of report subperiods).
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.)
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
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!
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).
Sort each group of siblings in an account tree by declaration order, then account name.
So each group will contain first the declared accounts,
in the same order as their account directives were parsed,
and then the undeclared accounts, sorted by account name.
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.
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.
Like accountNameInferType, but exclude the provided types from the guesses.
Used eg to prevent "equity:conversion" being inferred as Conversion when a different
account has been declared with that type.
Clip an account name to a given DepthSpec, first checking whether it
matches any of the regular expressions controlling depth. If so, clip to the
depth of the most specific of those matches, i.e. the one which starts
matching the latest as you progress up the parents of the account. Otherwise
clip to the flat depth provided, or return the full name if Nothing.
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.
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!
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"]
Calculate the depth to which an account name should be clipped for a given
DepthSpec.
First checking whether the account name matches any of the regular
expressions controlling depth. If so, clip to the depth of the most specific
of those matches, i.e. the one which starts matching the latest as you
progress up the parents of the account. Otherwise clip to the flat depth
provided, or return the full name if Nothing.
Do this Amount and (and its total cost, 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.
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.
We often want to display "infinite decimal" amounts rounded to some readable
number of digits, while still displaying amounts with a large but "non infinite"
number of decimal digits (eg 10 or 100 or 200 digits) in full.
This helper is like amountSetFullPrecision, but with some refinements:
A maximum display precision can be specified, setting a hard upper limit.
If no limit is specified, and the internal precision is the maximum (255),
indicating an infinite decimal, display precision is set to a smaller default (8).
This function always sets an explicit display precision (ie, Precision n).
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 costs or total costs
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
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.
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 cost commodity, then by
unit cost from most negative to most positive.
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.
Return an unnormalised MixedAmount containing just the amounts in the
requested commodity from the original mixed amount.
The result will contain at least one Amount of the requested commodity,
even if the original mixed amount did not (with quantity zero in that case,
and this would be discarded when the mixed amount is next normalised).
The result can contain more than one Amount of the requested commodity,
eg because there were several with different costs,
or simply because the original mixed amount was was unnormalised.
Invert an amount (replace its quantity q with 1/q).
The amount's transacted price, if any, is not changed.
An amount with zero quantity is left unchanged.
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.
In each component amount, increase the display precision sufficiently
to render it exactly if possible, but not more than the given max precision,
and if no max precision is given and the amount has infinite decimals,
limit display precision to a hard-coded smaller number (8).
See amountSetFullPrecisionUpTo.
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)".
Render an amount using its display style and the default amount format.
Zero-equivalent amounts are shown as just "0".
The special "missing" amount is shown as the empty string.
Render an amount using its display style and the given amount format, as a builder for efficiency.
(This can be converted to a Text with wbToText or to a String with wbUnpack).
The special "missing" amount is displayed as the empty string.
Render a mixed amount using its amount display styles and the default amount format,
after normalising it (to at most one amount in each of its commodities).
See showMixedAmountB for special cases.
Render a mixed amount using its amount display styles and the given amount format,
as a builder for efficiency.
(This can be converted to a Text with wbToText or to a String with wbUnpack).
Warning: this (and its showMixedAmount aliases above) basically assumes amounts have no costs.
It can show misleading costs or not show costs which are there.
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.
Zero-equivalent amounts are shown as just "0".
The special "missing" amount is shown as the empty string (?).
Like showMixedAmountOneLineWithoutCost, 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.
See showMixedAmountB for special cases.
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.
Get the one-line string representation of a mixed amount, but without
any @ costs.
With a True argument, adds ANSI codes to show negative amounts in red.
See showMixedAmountB for special cases.
Get the string representation of a mixed amount, without showing any costs.
With a True argument, adds ANSI codes to show negative amounts in red.
See showMixedAmountB for special cases.
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.
Balance this isolated 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.
Note this is not as accurate as balanceTransactionInJournal,
which considers the whole journal when calculating balance assignments and balance assertions.
Helper used by balanceSingleTransaction and balanceTransactionWithBalanceAssignmentAndCheckAssertionsB;
use one of those instead.
It also returns a list of accounts and amounts that were inferred.
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.
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).
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:
Example32 expressions
>>> :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"
refdate is Wednesday, 2008-11-26
>>> t "last wednesday"
"2008-11-19"
>>> t "this wednesday"
"2008-12-03"
>>> t "next wednesday"
"2008-12-03"
>>> t "last january"
"2008-01-01"
>>> t "this january"
"2009-01-01"
>>> t "next january"
"2009-01-01"
>>> t "last november"
"2007-11-01"
>>> t "this november"
"2009-11-01"
>>> t "next november"
"2009-11-01"
Example5 expressions
>>> 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"
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.
Find the next occurrence of the specified month and day of month, on or after the given date.
The month should be 1-12 and the day of month should be 1-31, or an error will be raised.
For given date d find week-long interval that starts on nth day of week
and covers it.
Examples: 2017-11-22 is Wed. Week-long intervals that cover it and
start on Mon, Tue or Wed will start in the same week. However
intervals that start on Thu or Fri should start in prev week:
>>> let wed22nd = fromGregorian 2017 11 22
>>> nthdayofweekcontaining 1 wed22nd
2017-11-20
>>> nthdayofweekcontaining 2 wed22nd
2017-11-21
>>> nthdayofweekcontaining 3 wed22nd
2017-11-22
>>> nthdayofweekcontaining 4 wed22nd
2017-11-16
>>> nthdayofweekcontaining 5 wed22nd
2017-11-17
A simple date parsing helper: parses these YMD date string formats:
`YYYY-MM-DD`, `YYYYMMDD`, YYYY.MM.DD or YYYYMMDD,
where the month and day each have two digits and the year has one or more.
This is different from the Smart Dates of the CLI and period expressions ("smartdate", below)
and not quite the same as the Simple Dates of the journal ("datep", in Hledger.Read.Common).
It's mainly for internal or interactive use, eg when debugging -
but currently is also used in a few user-facing places, such as:
parsing --value's argument,
parsing .latest files,
and parsing hledger's --version output (which uses unseparated dates).
Unseparated dates were added in 2025 for convenience.
Note it means many integers will now parse successfully.
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).
Example26 expressions
>>> 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 (MonthDay 2,DateSpan ..)>>> p "every 2nd day"Right (MonthDay 2,DateSpan ..)>>> p "every 2nd day 2009.."Right (MonthDay 2,DateSpan 2009-01-01..)>>> p "every 2nd day 2009-"Right (MonthDay 2,DateSpan 2009-01-01..)>>> p "every 29th Nov"Right (MonthAndDay 11 29,DateSpan ..)>>> p "every 29th nov ..2009"Right (MonthAndDay 11 29,DateSpan ..2008-12-31)>>> p "every nov 29th"Right (MonthAndDay 11 29,DateSpan ..)>>> p "every Nov 29th 2009.."Right (MonthAndDay 11 29,DateSpan 2009-01-01..)>>> p "every 11/29 from 2009"Right (MonthAndDay 11 29,DateSpan 2009-01-01..)>>> p "every 11/29 since 2009"Right (MonthAndDay 11 29,DateSpan 2009-01-01..)>>> p "every 2nd Thursday of month to 2009"Right (NthWeekdayOfMonth 2 4,DateSpan ..2008-12-31)>>> p "every 1st monday of month to 2009"Right (NthWeekdayOfMonth 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 (MonthDay 2,DateSpan ..)>>> p "every 2nd day"Right (MonthDay 2,DateSpan ..)>>> p "every 2nd day 2009.."Right (MonthDay 2,DateSpan 2009-01-01..)>>> p "every 2nd day of month 2009.."Right (MonthDay 2,DateSpan 2009-01-01..)
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)
last/this/next monday/mon (the previous or next named weekday; this=next)
last/next january/jan (previous or next start of named month; this disallowed to avoid confusion)
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)
Fill any unspecified dates in the first span with the dates from
the second one (if specified there). Sort of a one-way spanIntersect.
This one can create an invalid span that'll always be empty.
Extend the definite start/end dates of the first span, if needed,
to include the definite start/end dates of the second span.
Andor, replace open startend dates in the first span with
definite start/end dates from the second.
Unlike spanUnion, open start/end dates in the second are ignored.
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.
Find the start and end dates of the period within a DayPartition which contains a given day.
If the day is after the end of the last period, it is assumed to be within the last period.
If the day is before the start of the first period (ie, in the historical period),
only the historical period's end date is returned.
Convert DayPartition to a list of DateSpans.
Each span will end one day before the next span begins
(the span's exclusive end date will be equal to the next span's start date).
Convert DayPartition to a list (which will always be non-empty) of period start and end dates (both inclusive).
Each end date will be one day before the next period's start date.
Convert DayPartition to a non-empty list of period start and end dates (both inclusive).
Each end date will be one day before the next period's start date.
Split a DateSpan into a DayPartition consisting of consecutive exact
spans of the specified Interval, or Nothing if the span is invalid.
If no interval is specified, the original span is returned.
If the original span is the null date span, ie unbounded, Nothing is returned.
If the original span is empty, eg if the end date is <= the start date, Nothing is returned.
Date adjustment
Some intervals respect the "adjust" flag (years, quarters, months, weeks, every Nth weekday
of month seem to be the ones that need it). This will move the start date earlier, if needed,
to the previous natural interval boundary (first of year, first of quarter, first of month,
monday, previous Nth weekday of month). Related: #1982 #2218
The end date is always moved later if needed to the next natural interval boundary,
so that the last period is the same length as the others.
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.
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.
Given a problem price directive,
and maybe a function to calculate the error region's column(s) (currently ignored):
generate a megaparsec-style error message with highlighted excerpt.
Returns the source file path, line number, column(s) if known, and the rendered excerpt,
or as much of these as possible.
Columns will be accurate for the rendered error message, not for the original journal entry.
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.
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.
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.
All raw amounts appearing in this journal, with MixedAmounts flattened, in no particular order.
(Including from posting amounts, cost amounts, P directives, and the last D directive.)
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.
The account name to use for conversion postings generated by --infer-equity.
This is the first account declared with type V/Conversion,
or otherwise the defaultBaseConversionAccount (equity:conversion).
Sorted unique commodity symbols mentioned anywhere in this journal.
(Including commodity directives, P directives, the last D directive, posting amounts and cost amounts.)
Sorted unique commodity symbols used anywhere in this journal, including
commodity directives, P directives, the last D directive, posting amounts and cost amounts.
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.
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.
All the accounts in this journal which are declared or inferred as V/Conversion type.
This does not include new account names which might be generated by --infer-equity, currently.
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.
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.
Collect and save inferred amount styles for each commodity based on
P directive amounts, posting amounts but not cost amounts, and maybe the last D amount, in that commodity.
Can return an error message eg if inconsistent number formats are found.
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.
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.
To all postings in the journal, add any tags from their account
(including those inherited from parent accounts).
If a tag already exists on the posting, it is not changed (the account tag will be ignored).
To all postings in the journal, add any tags from their amount's commodities.
If a tag already exists on the posting, it is not changed (the commodity tag will be ignored).
Remove all tags from the journal's postings except those provided by their account.
This is useful for the accounts report.
It does not remove tag declarations from the posting comments.
Renumber all the account declarations. This is useful to call when
finalising or concatenating Journals, to give account declarations
a total order across files.
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.
Identify and tag (1) equity conversion postings and (2) postings which have (or could have ?) redundant costs.
And if the addcosts flag is true, also add any costs which can be inferred from equity conversion postings.
This is always called before transaction balancing to tag the redundant-cost postings so they can be ignored.
With --infer-costs, it is called again after transaction balancing (when it has more information to work with) to infer costs from equity postings.
See transactionTagCostsAndEquityAndMaybeInferCosts for more details, and hledger manual > Cost reporting for more background.
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.
Check all balance assertions in the journal and return an error message if any of them fail.
(Technically, this also tries to balance the journal and can return balancing failure errors;
ensure the journal is already balanced (with journalBalanceTransactions) to avoid this.)
Check that all the commodities used in this journal's postings and P directives
have been declared by commodity directives, returning an error message otherwise.
Check that all the journal's tags (on accounts, transactions, postings..)
have been declared with tag directives, returning an error message otherwise.
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.
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.
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.
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.
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.
Like showPeriod, but if it's a month or week period show
an abbreviated form.
>>> showPeriodAbbrev (WeekPeriod (fromGregorian 2016 7 25))
W30
>>> showPeriodAbbrev (WeekPeriod (fromGregorian 2024 12 30))
W01
Get the data for the period containing the given Day, and that period's start date.
If the day is after the end of the last period, it is assumed to be within the last period.
If the day is before the start of the first period (ie, in the historical period), return Nothing.
Get the data for the period containing the given Day, and that period's start date.
If the day is after the end of the last period, it is assumed to be within the last period.
If the day is before the start of the first period (ie, in the historical period),
return the data for the historical period and no start date.
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).
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.
Example2 expressions
>>> 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.002017-02-01 ; generated-transaction: ~ monthly from 2017/1 to 2017/4 a $1.002017-03-01 ; generated-transaction: ~ monthly from 2017/1 to 2017/4 a $1.00
Example1 expression
>>> _ptgen "monthly from 2017/1 to 2017/5"2017-01-01 ; generated-transaction: ~ monthly from 2017/1 to 2017/5 a $1.002017-02-01 ; generated-transaction: ~ monthly from 2017/1 to 2017/5 a $1.002017-03-01 ; generated-transaction: ~ monthly from 2017/1 to 2017/5 a $1.002017-04-01 ; generated-transaction: ~ monthly from 2017/1 to 2017/5 a $1.00
Example1 expression
>>> _ptgen "every 2nd day of month from 2017/02 to 2017/04"2017-02-02 ; generated-transaction: ~ every 2nd day of month from 2017/02 to 2017/04 a $1.002017-03-02 ; generated-transaction: ~ every 2nd day of month from 2017/02 to 2017/04 a $1.00
Example1 expression
>>> _ptgen "every 30th day of month from 2017/1 to 2017/5"2017-01-30 ; generated-transaction: ~ every 30th day of month from 2017/1 to 2017/5 a $1.002017-02-28 ; generated-transaction: ~ every 30th day of month from 2017/1 to 2017/5 a $1.002017-03-30 ; generated-transaction: ~ every 30th day of month from 2017/1 to 2017/5 a $1.002017-04-30 ; generated-transaction: ~ every 30th day of month from 2017/1 to 2017/5 a $1.00
Example1 expression
>>> _ptgen "every 2nd Thursday of month from 2017/1 to 2017/4"2017-01-12 ; generated-transaction: ~ every 2nd Thursday of month from 2017/1 to 2017/4 a $1.002017-02-09 ; generated-transaction: ~ every 2nd Thursday of month from 2017/1 to 2017/4 a $1.002017-03-09 ; generated-transaction: ~ every 2nd Thursday of month from 2017/1 to 2017/4 a $1.00
Example1 expression
>>> _ptgen "every nov 29th from 2017 to 2019"2017-11-29 ; generated-transaction: ~ every nov 29th from 2017 to 2019 a $1.002018-11-29 ; generated-transaction: ~ every nov 29th from 2017 to 2019 a $1.00
Example1 expression
>>> _ptgen "2017/1"2017-01-01 ; generated-transaction: ~ 2017/1 a $1.00
Example1 expression
>>> 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))[]
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.
Special tags hledger sometimes adds to mark various things.
These should be hidden tag names, beginning with _.
With --verbose-tags, the equivalent visible tags will also be added.
These tag names are mentioned in docs and can be matched by user queries, so consider the impact before changing them.
Special tags hledger sometimes adds to mark various things.
These should be hidden tag names, beginning with _.
With --verbose-tags, the equivalent visible tags will also be added.
These tag names are mentioned in docs and can be matched by user queries, so consider the impact before changing them.
Special tags hledger sometimes adds to mark various things.
These should be hidden tag names, beginning with _.
With --verbose-tags, the equivalent visible tags will also be added.
These tag names are mentioned in docs and can be matched by user queries, so consider the impact before changing them.
Special tags hledger sometimes adds to mark various things.
These should be hidden tag names, beginning with _.
With --verbose-tags, the equivalent visible tags will also be added.
These tag names are mentioned in docs and can be matched by user queries, so consider the impact before changing them.
Special tags hledger sometimes adds to mark various things.
These should be hidden tag names, beginning with _.
With --verbose-tags, the equivalent visible tags will also be added.
These tag names are mentioned in docs and can be matched by user queries, so consider the impact before changing them.
Add the given hidden tag to a posting; and with a true argument,
also add the equivalent visible tag to the posting's tags and comment fields.
If the posting already has these tags (with any value), do nothing.
Generate equity conversion postings corresponding to a Posting's cost(s)
(one pair of conversion postings per cost), wherever they don't already exist.
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.
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.
Apply a specified valuation to this posting's amount, using the
provided price oracle, commodity styles, and reference dates.
See amountApplyValuation.
Render one posting, on one or more lines, suitable for print output.
Also returns the widths calculated for the account and amount fields.
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.
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.
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.
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".
Render a transaction's postings as indented lines, suitable for print output.
Normally these will be in valid journal syntax which hledger can reparse
(though they may include no-longer-valid balance assertions).
Explicit amounts are shown, 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.
Posting amounts will be aligned with each other, starting about 4 columns
beyond the widest account name (see postingAsLines for details).
The postings will appear balanced (amounts summing to zero).
Amounts' display precisions, which may have been limited by commodity directives,
will be increased if necessary to ensure this.
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.
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...
Convert timeclock entries to journal transactions.
This is the new, default version added in hledger 1.43 and improved in 1.50.
It allows concurrent clocked-in sessions (though not with the same account name),
and clock-in/clock-out entries in any order.
Entries are processed in parse order.
Sessions crossing midnight are split into days to give accurate per-day totals.
At the end, any sessions with no clockout get an implicit clockout with the provided "now" time.
If any entries cannot be paired as expected, an error is raised.
Convert timeclock entries to journal transactions.
This is the old version from hledger <1.43, now enabled by --old-timeclock.
It requires strictly alternating clock-in and clock-entries.
It was documented as allowing only one clocked-in session at a time,
but in fact it allows concurrent sessions, even with the same account name.
Entries must be a strict alternation of in and out, beginning with in.
When there is no clockout, one is added with the provided current time.
Sessions crossing midnight are split into days to give accurate per-day totals.
If entries are not in the expected in/out order, an error is raised.
Parse a transaction's description into payee and note (aka narration) fields,
assuming a convention of separating these with | (like Beancount).
Ie, everything up to the first | is the payee, everything after it is the note.
When there's no |, payee == note == description.
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).
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.
Add the given hidden tag to a transaction; and with a true argument,
also add the equivalent visible tag to the transaction's tags and comment fields.
If the transaction already has these tags (with any value), do nothing.
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.
Apply a specified valuation to this transaction's amounts, using
the provided price oracle, commodity styles, and reference dates.
See amountApplyValuation.
Like transactionCommodityStyles, but attach a particular rounding strategy to the styles,
affecting how they will affect display precisions when applied.
Find, associate, and tag the corresponding equity conversion postings and costful or potentially costful postings in this transaction.
With a true addcosts argument, also generate and add any equivalent costs that are missing.
The (previously detected) names of all equity conversion accounts should be provided.
For every pair of adjacent conversion postings, this first searches for a posting with equivalent cost (1).
If no such posting is found, it then searches the costless postings, for one matching one of the conversion amounts (2).
If either of these found a candidate posting, it is tagged with costPostingTagName.
Then if in addcosts mode, if a costless posting was found, a cost equivalent to the conversion amounts is added to it.
The name reflects the complexity of this and its helpers; clarification is ongoing.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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).
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).
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.
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
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.
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.
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.
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.
Get the default journal file path - either $LEDGER_FILE or $HOME/.hledger.journal file.
This looks for the LEDGER_FILE environment variable, like Ledger.
The value should be a file path, possibly with ~ at the start meaning the current user's home directory.
Or the value can be a glob pattern (containing *, ?, [ or {) ), in which case the first matching file path is used.
When it's a glob pattern that matches no existing files, an error is raised.
If LEDGER_FILE is unset or set to the empty string, this returns a default file path:
.hledger.journal in the user's home directory,
or if we can't find the user's home directory, in the current directory.
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).
Read a Journal from some handle, 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,
the journal reader is used.
If a file path is not provided, "-" is assumed (and may appear in error messages,
files output etc, where it will be a slight lie: it will mean "not from a file",
not necessarily "from standard input".
Read a Journal from this file, or from stdin if the file path is -,
with strict checks if enabled, or return an error message.
XXX or, calls error if the file does not exist.
(Note strict checks are disabled temporarily here when this is called by readJournalFiles).
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 not deferred by readJournalFiles, 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 processed.
Read a Journal from each specified file path (using readJournalFile)
and combine them into one; or return the first error message.
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.
Strict checks, if enabled, are temporarily deferred until all files are read,
to ensure they see the whole journal, and/or to avoid redundant work.
(Some checks, like assertions and ordereddates, might still be doing redundant work ?)
Writing .latest files, if enabled, is also deferred till the end,
and is done only if strict checks pass.
Like readJournalFile, but if the file does not exist, returns an empty journal
with the file path set. This is useful for commands like add and import that
need to work with a potentially non-existent journal file.
Like readJournalFiles, but if the first file does not exist, provides an empty
journal with that file path set. Other files must exist as normal.
This is useful for commands like add and import that write to the first file,
which might not exist yet, while also reading other files for completions etc.
If the specified journal file does not exist (and is not "-"), call error with an informative message.
(Using "journal file" generically here; it could be in any of hledger's supported formats.)
Save the given latest date(s) seen in the given data FILE,
in a hidden file named .latest.FILE, creating it if needed.
Unless no latest dates are provided, in which case do nothing.
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.
(We should have required them to start with an alphanumeric, but didn't.)
Note, this means account names can contain all kinds of punctuation, including ; which usually starts a following comment.
Parent parsers usually remove the following comment before using this parser.
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.)
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.
Example1 expression
>>> either (Left . customErrorBundlePretty) Right $ rtp (bracketeddatetagsp Nothing) "[2016/1/2=3/4]"Right [("date",2016-01-02),("date2",2016-03-04)]
Example1 expression
>>> either (Left . customErrorBundlePretty) Right $ rtp (bracketeddatetagsp Nothing) "[1]"Left ...not a bracketed date...
Example1 expression
>>> either (Left . customErrorBundlePretty) Right $ rtp (bracketeddatetagsp Nothing) "[2016/1/32]"Left ...1:2:...This is not a valid date...
Example1 expression
>>> either (Left . customErrorBundlePretty) Right $ rtp (bracketeddatetagsp Nothing) "[1/31]"Left ...1:2:...This partial date can not be parsed because the current year is unknown...
Example1 expression
>>> either (Left . customErrorBundlePretty) Right $ rtp (bracketeddatetagsp Nothing) "[0123456789/-.=/-.=]"Left ...1:13:...expecting month or day...
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.
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).
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. See also emptyorcommentlinep2.
A newer comment line parser.
Parses a line which is empty, all blanks, or whose first non-blank character is one of those provided.
A final newline is optional.
Parse a comment following a journal item, possibly continued on multiple lines,
and return the comment text.
Example5 expressions
>>> rtp followingcommentp "" -- no commentRight "">>> rtp followingcommentp ";" -- just a (empty) same-line comment. newline is addedRight "\n">>> rtp followingcommentp "; \n"Right "\n">>> rtp followingcommentp ";\n ;\n" -- a same-line and a next-line commentRight "\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"
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)
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.
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 finalisatison, as in parsing
Timeclock and Timedot files.
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.
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.
Parse an account name plus one following space if present (see accountnamep);
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.
The flag says whether account names may include semicolons; currently account names
in journal format may, but account names in timeclock/timedot formats may not.
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.
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.
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.
Example2 expressions
>>> let getTags (_,tags,_,_) = tags>>> let parseTags = fmap getTags . rtp (postingcommentp Nothing)
Example1 expression
>>> 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.
Example2 expressions
>>> let getDates (_,_,d1,d2) = (d1, d2)>>> let parseDates = fmap getDates . rtp (postingcommentp (Just 2000))
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)
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.
The first line of a transaction may be followed a 1-or-more-lines comment,
beginning with a semicolon possibly preceded by whitespace on the current line,
or with an indented semicolon on the next line. Additional lines also must
begin with an indented semicolon.
See also followingcommentpWith.
200011 ; a transaction comment starting on the same line ...
; extending to the next line
account1 $1
account2
Tags are name-value pairs.
Example2 expressions
>>> let getTags (_,tags) = tags>>> let parseTags = fmap getTags . rtp transactioncommentp
Example1 expression
>>> 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.
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.
Find the reader named by mformat, if provided.
("ssv" and "tsv" are recognised as alternate names for the csv reader,
which also handles those formats.)
Or, if a file path is provided, find the first reader that handles
its file extension, if any.
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.
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.
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).
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.
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).
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.
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).
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.
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.
Generate one postings report line item, containing the posting,
the current running balance, and optionally the posting date and/or
the transaction description.
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.
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.
Select the Account valuation functions required for performing valuation after summing
amounts. Used in MultiBalanceReport to value historical and similar reports.
Generate a ReportOpts from raw command-line input, given a day and whether to use ANSI colour/styles in standard output.
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,
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).
The effective report span is the start and end dates requested by options or queries.
If the start date is unspecified, the earliest transaction or posting date is used.
If the end date is unspecified, the latest transaction or posting date
(or non-future market price date, when doing an end value report) is used.
If none of these things are present, the null date span is returned.
The report sub-periods caused by a report interval, if any, are also returned.
If the ReportOpts specify that we will need to consider historical
postings, either because this is a historical report, or because the
valuation strategy requires historical amounts.
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.
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.
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
vvaluemapM' :: Monadf => (a -> fb) -> [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.
The program's debug output verbosity, from 0 to 9.
The default is 0 meaning no debug output.
This can be overridden by running the program with a --debug [1-9] command line option;
a --debug flag with no value means 1.
Uses unsafePerformIO to read the command line.
When running in GHCI, changing this requires reloading this module.
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.
When ghc-debug support has been built into the program and enabled at runtime with --debug=-N,
this calls ghc-debug's withGhcDebug; otherwise it's a no-op.
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".
Get the value of the rightmost --color or --colour option from the program's command line arguments.
Throws an error if the option's value could not be parsed.
Like expandPath, but treats the expanded path as a glob, and returns
zero or more matched absolute file paths, alphabetically sorted.
Can raise an error.
For a more elaborate glob expander, see findMatchedFiles (used by the include directive).
Given a current directory, convert a possibly relative, possibly tilde-prefixed
file path to an absolute one.
~username is not supported.
If the file path is "-", it is left as-is.
This can an raise an IO error.
Like expandPath, but if the path contains glob metacharacters (* ? [ {),
treats it as a glob pattern and expands it, returning the first match.
Raises an error if the glob pattern matches no files.
If the path contains no glob metacharacters, just expands ~ and returns the path,
even if the file doesn't exist yet.
This is useful for options like -f and LEDGER_FILE that should:
- accept non-existent files (for commands like add/import that create them)
- expand glob patterns and error if they don't match anything
Try to find a pager executable robustly, safely handling various error conditions
like an unset PATH var or the specified pager not being found as an executable.
The pager can be specified by a path or program name in the PAGER environment variable.
If that is unset or has a problem, "less" is tried, then "more".
If successful, the pager's path or program name is returned.
Given one or more long or short flag names,
report whether this flag is present in the command line.
Concatenated short flags (-a -b written as -ab) are not supported.
Given one or more long or short option names, read the rightmost value of this option from the command line arguments.
If the value is missing raise an error.
Concatenated short flags (-a -b written as -ab) are not supported.
Read text from a handle, perhaps using a specified encoding from the encoding package.
Or if no encoding is specified, using the handle's current encoding,
changing it to UTF-8BOM if it was UTF-8, to ignore any Byte Order Mark at the start.
Also it converts Windows line endings to newlines.
If decoding fails, this throws an IOException (or possibly a UnicodeException or something else from the encoding package).
This wraps a program's main routine so as to display more consistent,
useful, and GHC-version-independent error output when the program exits
because of certain common exceptions. It
disables SIGPIPE errors, which are usually harmless,
caused when our output is truncated in a piped command.
catches these common exceptions:
UnicodeException, caused eg by text decoding errors in pure code
IOException, caused by IO errors, including text decoding errors during IO
ErrorCall - error / errorWithoutStackTrace calls
compensates for GHC output bugs:
removes the trailing newlines added by some GHC 9.10.* versions
removes "uncaught exception" output added by some GHC 9.12.* versions
ensures a consistent "PROGNAME: " prefix
applies bold bright red ANSI styling to the first line of error output,
if that is supported and allowed
for unicode exceptions and I/O exceptions which look like they were
unicode-related, it adds a message (in english) explaining the problem and what to do.
Some exceptions this does not catch are ExitCode (exitSuccessexitFailureexitWith)
and UserInterrupt (control-C).
Test less, by running less --version and looking for a nonzero exit, timeout, or stderr output.
Uses the provided environment, containing a LESS variable, if any.
We do this because various LESS settings can cause some less versions to fail or cause confusing output without failing.
Compute the LESS environment variable value that hledger will use for the less pager.
This used in runPager when invoking less, and also in the setup command for display.
It takes the current HLEDGER_LESS and LESS env var values, and whether we are showing colour on stdout,
and returns the adjusted LESS value that should be used. Specifically:
If HLEDGER_LESS is defined, we use it in place of the LESS environment variable.
Otherwise, if LESS is defined, append some preferred options (lessOptions and maybe lessColourOptions) to it.
Otherwise, we set LESS to just use those preferred options.
Print an error message to stderr, with a consistent "programname: " prefix,
and applying ANSI styling (bold bright red) to the first line if that is supported and allowed.
The program's command line arguments.
Uses unsafePerformIO; tends to stick in GHCI until reloaded,
and may or may not detect args provided by a hledger config file.
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.
Display the given text on the terminal, trying to use a pager ($PAGER, less, or more)
when appropriate (see maybePagerFor), otherwise printing to standard output.
Also, if the pager is less, we modify the LESS environment variable (see lessVarValue)
and check for problems which could cause confusing output (see lessIsWorking).
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.
Detect the terminal's current background lightness (0..1), if possible, using unsafePerformIO.
If the terminal is transparent, its apparent lightness may be different.
Like useColorOnStdout, but using unsafePerformIO. Useful eg for low-level debug code.
Sticky in GHCI until reloaded, may not always be affected by --color in a hledger config file, etc.
Show a warning message on stderr before returning the given value.
Like trace, but prepends a "Warning:" label, and does some ANSI styling of the first line when allowed (using unsafe IO).
Currently we use this very sparingly in hledger; we prefer to either quietly work, or loudly raise an error.
Varying output can make scripting harder. But on stderr, it shouldn't cause much hassle.
Attach a filepath and source text to a "final" parse error so that it can be pretty-printed.
You must ensure that you provide the appropriate source text and filepath.
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.
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.
See also: Hledger.Utils.Debug, megaparsec's dbg.
Uses unsafePerformIO.
XXX Can be hard to make this evaluate.
'excerpt_ p' applies the given parser p and extracts the portion of
the source consumed by p, along with the source position of this
portion. This is the only way to create a source excerpt suitable for
"re-parsing" by reparseExcerpt.
Pretty-print a "final" parse error: print the stack of include files,
then apply the pretty-printer for parse error bundles.
Note that attachSource must be used on a "final" parse error before it can be pretty-printed.
Fail at a specific source interval, given by the raw offsets of its
endpoints from the start of the input stream (the numbers of tokens
processed at those points).
Note that care must be taken to ensure that the specified interval does
not span multiple lines of the input source. This will not be checked.
Parse an include file with the given parser and initial state,
discarding the resulting state,
and re-throwing any parse errors as final parse errors with the file's info attached.
'reparseExcerpt s p' "re-parses" the source excerpt s using the
parser p. Parse errors raised by p will be re-thrown at the source
position of the source excerpt.
In order for the correct source file to be displayed when re-throwing
parse errors, we must ensure that the source file during the use of
'reparseExcerpt s p' is the same as that during the use of excerpt_
that generated the source excerpt s. However, we can usually expect
this condition to be satisfied because, at the time of writing, the
only changes of source file in the codebase take place through include
files, and the parser for include files neither accepts nor returns
SourceExcerpts.
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.
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).
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.
Double-width-character-aware string truncation. Take as many
characters as possible from a string without exceeding the
specified width. Eg takeWidth 3 "りんご" = "り".
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.
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.
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.
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.
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).
Double-width-character-aware string truncation. Take as many
characters as possible from a string without exceeding the
specified width. Eg textTakeWidth 3 "りんご" = "り".
Creates a new process from the provided CreateProcess, and wait for it
to finish. If the process returns a non-zero exit code, an exception is
raised.
If an asynchronous exception is thrown to the thread executing
callCreateProcess, the forked process will be terminated and
callCreateProcess will wait (block) until the process has been
terminated.
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" []){ 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.
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.
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.
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.
The computation rawSystemcmdargs 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.
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.
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.
Given a program p and arguments args,
showCommandForUser pargs returns a string suitable for pasting
into /bin/sh (on Unix systems) or CMD.EXE (on Windows).
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.
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.
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.
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
CreatePipeHandles are closed. In particular this means that if the
Haskell thread is killed (e.g. killThread), that the external process is
also terminated.
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:
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 responsibility to register the handle if it supports
async access.
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.
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.
IO a is an action which returns the acquired resource.
Despite it being an IO action, the resource it returns will be
acquired only once and shared across all the tests in the tree.
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.
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 Test.Tasty.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.
Create a named group of test cases or other groups. Tests are executed in
order and each test is considered a dependency of the next one.
If filtering by TestPattern (--pattern) is in action,
any test matching the pattern also shields earlier tests from filtering out,
even if they themselves do not match the pattern.
For parallel execution, see testGroup. For ordered test execution, but
with default filtering behavior, see inOrderTestGroup.
Note that this is will only work when used with the default TestManager.
If you use another manager, like tasty-rerun for instance, sequentiality
might possibly be ignored.
Create a named group of test cases that will be played sequentially,
in the exact order provided. Similarly to testGroup
and in contrast to dependentTestGroup,
filtering by TestPattern is applied uniformly.
Note that this is will only work when used with the default TestManager.
If you use another manager, like tasty-rerun for instance, the fact that
these tests should be run in the given order might possibly be ignored.
Like testCase, except in case the test succeeds, the returned string
will be shown as the description. If the empty string is returned, it
will be ignored.
Asserts that the specified actual value is equal to the expected value.
The output message will contain the prefix, the expected value, and the
actual value.
If the prefix is the empty string (i.e., ""), then the prefix is omitted
and only the expected and actual values are output.
main = defaultMain $ testCaseSteps "Multi-step test" $ \step -> do
step "Preparing..."
-- do something
step "Running part 1"
-- do something
step "Running part 2"
-- do something
assertFailure "BAM!"
step "Running part 3"
-- do something
The step calls are mere annotations. They let you see which steps were
performed successfully, and which step failed.
You can think of step
as putStrLn, except putStrLn would mess up the output with the
console reporter and get lost with the others.
For the example above, the output will be
Multi-step test: FAIL
Preparing...
Running part 1
Running part 2
BAM!
1 out of 1 tests failed (0.00s)
Note that:
Tasty still treats this as a single test, even though it consists of
multiple steps.
The execution stops after the first failure. When we are looking at
a failed test, we know that all displayed steps but the last one were
successful, and the last one failed. The steps after the failed one
are not displayed, since they didn't run.
Calendrical difference, with as many whole months as possible.
Has the property addGregorianDurationClip (diffGregorianDurationClip d2 d1) d1 = d2.
For example, 2027-03-01 - 2027-01-31 = 1 month and 1 day.
Calendrical difference, with as many whole months as possible.
Has the property addGregorianDurationRollOver (diffGregorianDurationRollOver d2 d1) d1 = d2.
For example, 2027-03-01 - 2027-01-31 = 29 days.
year of century for ISO 8601 Week Date format, 0-padded to two chars,
00
-
99
%f
century for ISO 8601 Week Date format, no padding. Note
%0f
and
%_f
pad to two chars
%V
week of year for ISO 8601 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.
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.
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
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.
QSemN is a quantity semaphore in which the resource is acquired
and released in arbitrary amounts. It provides guaranteed FIFO ordering
for satisfying blocked waitQSemN calls.
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.
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.
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.
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.
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:
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.
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.
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.
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 systems, the default is ~/.local/state. On
Windows, the default is %LOCALAPPDATA%
(e.g. C:/Users/<user>/AppData/Local).
Instances6Bounded, Enum, Eq, Ord, Read, Show
BoundedXdgDirectoryDefined in directory-1.3.11.0 · System.Directory.Internal.Common
EnumXdgDirectoryDefined in directory-1.3.11.0 · System.Directory.Internal.Common
EqXdgDirectoryDefined in directory-1.3.11.0 · System.Directory.Internal.Common
OrdXdgDirectoryDefined in directory-1.3.11.0 · System.Directory.Internal.Common
ReadXdgDirectoryDefined in directory-1.3.11.0 · System.Directory.Internal.Common
ShowXdgDirectoryDefined in directory-1.3.11.0 · System.Directory.Internal.Common
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).
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).
>>> some (putStr "la")lalalalalalalalala... * goes on forever *
Example1 expression
>>> some Nothingnothing
Example1 expression
>>> take 5 <$> some (Just 1)* hangs forever *
Note that this function can be used with Parsers based on
Applicatives. In that case some parser will attempt to
parse parser one or more times until it fails.
>>> many (putStr "la")lalalalalalalalala... * goes on forever *
Example1 expression
>>> many NothingJust []
Example1 expression
>>> take 5 <$> many (Just 1)* hangs forever *
Note that this function can be used with Parsers based on
Applicatives. In that case many parser will attempt to
parse parser zero or more times until it fails.
sequence computations and combine their results (<*> and liftA2).
A minimal complete definition must include implementations of pure
and one of either <*> or liftA2. If it defines both, then they must behave
the same as their default definitions:
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.
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.
Example1 expression
>>> Just 2 *> Just 3Just 3
Example1 expression
>>> Nothing *> Just 3Nothing
Of course a more interesting use case would be to have effectful
computations instead of just returning pure values.
Example4 expressions
>>> import Data.Char>>> import GHC.Internal.Text.ParserCombinators.ReadP>>> let p = string "my name is " *> munch1 isAlpha <* eof>>> readP_to_S p "my name is Simon"[("Simon","")]
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:
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 these articles by School of Haskell or
David Luposchainsky
for an explanation.
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:
Example2 expressions
>>> fmap show NothingNothing>>> fmap show (Just 3)Just "3"
Convert from an Either Int Int to an
Either Int String using show:
Example2 expressions
>>> fmap show (Left 17)Left 17>>> fmap show (Right 17)Right "17"
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:
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:
Example2 expressions
>>> 'a' <$ Just 2Just 'a'>>> 'a' <$ NothingNothing
FunctorResponseDefined in http-client-0.7.19 · Network.HTTP.Client.Types
FunctorRootDefined in math-functions-0.3.4.4 · Numeric.RootFinding
FunctorSequenceDefined in math-functions-0.3.4.4 · Numeric.Series
FunctorErrorFancyDefined in megaparsec-9.5.0 · Text.Megaparsec.Error
FunctorErrorItemDefined in megaparsec-9.5.0 · Text.Megaparsec.Error
FunctorPackerDefined in memory-0.18.0 · Data.ByteArray.Pack.Internal
FunctorChunkDefined in optparse-applicative-0.18.1.0 · Options.Applicative.Help.Chunk
FunctorComplResultDefined in optparse-applicative-0.18.1.0 · Options.Applicative.Internal
FunctorCompletionDefined in optparse-applicative-0.18.1.0 · Options.Applicative.Internal
FunctorPDefined in optparse-applicative-0.18.1.0 · Options.Applicative.Internal
FunctorCReaderDefined in optparse-applicative-0.18.1.0 · Options.Applicative.Types
FunctorOptReaderDefined in optparse-applicative-0.18.1.0 · Options.Applicative.Types
FunctorOptionDefined in optparse-applicative-0.18.1.0 · Options.Applicative.Types
FunctorParserDefined in optparse-applicative-0.18.1.0 · Options.Applicative.Types
FunctorParserFailureDefined in optparse-applicative-0.18.1.0 · Options.Applicative.Types
FunctorParserInfoDefined in optparse-applicative-0.18.1.0 · Options.Applicative.Types
FunctorParserMDefined in optparse-applicative-0.18.1.0 · Options.Applicative.Types
FunctorParserResultDefined in optparse-applicative-0.18.1.0 · Options.Applicative.Types
FunctorReadMDefined in optparse-applicative-0.18.1.0 · Options.Applicative.Types
FunctorConsumedDefined in parsec-3.1.18.0 · Text.Parsec.Prim
FunctorAnnotDetailsDefined in pretty-1.1.3.6 · Text.PrettyPrint.Annotated.HughesPJ
FunctorDocDefined in pretty-1.1.3.6 · Text.PrettyPrint.Annotated.HughesPJ
FunctorSpanDefined in pretty-1.1.3.6 · Text.PrettyPrint.Annotated.HughesPJ
FunctorDocDefined in prettyprinter-1.7.2 · Prettyprinter.Internal
Alter the document’s annotations.
This instance makes Doc more flexible (because it can be used in
Functor-polymorphic values), but fmap is much less readable compared to
using reAnnotate in code that only works for Doc anyway. Consider
using the latter when the type does not matter.
FunctorFlattenResultDefined in prettyprinter-1.7.2 · Prettyprinter.Internal
This instance makes SimpleDocStream more flexible (because it can be used in
Functor-polymorphic values), but fmap is much less readable compared to
using reAnnotateST in code that only works for SimpleDocStream anyway.
Consider using the latter when the type does not matter.
FunctorSimpleDocTreeDefined in prettyprinter-1.7.2 · Prettyprinter.Render.Util.SimpleDocTree
Alter the document’s annotations.
This instance makes SimpleDocTree more flexible (because it can be used in
Functor-polymorphic values), but fmap is much less readable compared to
using reAnnotateST in code that only works for SimpleDocTree anyway.
Consider using the latter when the type does not matter.
FunctorArrayDefined in primitive-0.9.1.0 · Data.Primitive.Array
FunctorSmallArrayDefined in primitive-0.9.1.0 · Data.Primitive.SmallArray
FunctorPackerDefined in ram-0.22.1 · Data.ByteArray.Pack.Internal
FunctorCharMapDefined in regex-tdfa-1.3.2.6 · Data.IntMap.CharMap2
FunctorReqDefined in req-3.13.4 · Network.HTTP.Req
FunctorResultDefined in shakespeare-2.2.0 · Text.Hamlet.Parse
FunctorSTMDefined in stm-2.5.3.1 · Control.Sequential.STM
FunctorMaybeDefined in strict-0.5.1 · Data.Strict.Maybe
FunctorHeaderDefined in tabular-0.2.2.8 · Text.Tabular
FunctorParserDefined in tasty-1.5.4 · Test.Tasty.Patterns.Parser
FunctorWindowDefined in terminal-size-0.3.4 · System.Console.Terminal.Common
FunctorCapabilityDefined in terminfo-0.4.1.7 · System.Console.Terminfo.Base
FunctorLocalTimeDefined in time-hourglass-0.3.0 · Time.LocalTime
FunctorHandshakeMDefined in tls-2.4.9 · Network.TLS.Handshake.State
FunctorRecordMDefined in tls-2.4.9 · Network.TLS.Record.State
FunctorTLSStDefined in tls-2.4.9 · Network.TLS.State
FunctorVectorDefined in vector-0.13.2.0 · Data.Vector
FunctorIdDefined in vector-0.13.2.0 · Data.Vector.Fusion.Util
FunctorVectorDefined in vector-0.13.2.0 · Data.Vector.Strict
FunctorBoxDefined in vector-stream-0.1.0.1 · Data.Stream.Monadic
FunctorBoolPairDefined in witherable-0.5 · Witherable
FunctorBasicIODefined in wizards-1.0.3 · System.Console.Wizard.BasicIO
FunctorHaskelineDefined in wizards-1.0.3 · System.Console.Wizard.Haskeline
FunctorWithSettingsDefined in wizards-1.0.3 · System.Console.Wizard.Haskeline
FunctorArbitraryIODefined in wizards-1.0.3 · System.Console.Wizard.Internal
FunctorCharacterDefined in wizards-1.0.3 · System.Console.Wizard.Internal
FunctorLineDefined in wizards-1.0.3 · System.Console.Wizard.Internal
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.
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
An alternative name for this function is 'bind', because it
is used to introduce bindings in monadic contexts, but some people may
refer to it as 'flatMap', which results from it being equivalent to
\x f -> join (fmap f x) :: Monad m => m a -> (a -> m b) -> m b
which can be seen as mapping a value with
Monad m => m a -> m (m b) and then 'flattening' m (m b) to m b using join.
Sequentially compose two actions, discarding any value produced
by the first, like sequencing operators (such as the semicolon)
in imperative languages.
Inject a value into the monadic type.
This function should not be different from its default implementation
as pure. The justification for the existence of this function is
merely historic.
Instances163Monad, …
MonadGenDefined in QuickCheck-2.18.0.0 · Test.QuickCheck.Gen
MonadRoseDefined in QuickCheck-2.18.0.0 · Test.QuickCheck.Property
MonadIResultDefined in aeson-2.2.5.1 · Data.Aeson.Types.Internal
MonadParserDefined in aeson-2.2.5.1 · Data.Aeson.Types.Internal
MonadResultDefined in aeson-2.2.5.1 · Data.Aeson.Types.Internal
MonadGetDefined in asn1-encoding-0.9.6 · Data.ASN1.Get
MonadComplexDefined in base-4.23.0.0 · Data.Complex
MonadFirstDefined in base-4.23.0.0 · Data.Semigroup
MonadLastDefined in base-4.23.0.0 · Data.Semigroup
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:
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 (==). Users who expect a stronger guarantee are advised
to write their own min and/or max functions.
The nuance of the above distinction is not always fully internalized by
developers, and in the past (tracing back to the Haskell 1.4 Report) the
specification for Ord asserted the stronger property that (min x y, max x
y) = (x, y) or (y, x), or in other words, that min and maxwill
return one of their arguments, using argument order as the tie-breaker if
the arguments are equal by comparison. A few list and
Foldable functions have behavior that is best understood
with this assumption in mind: all variations of minimumBy and maximumBy
(which can't use min and max in their implementations) are written such
that minimumBy compare and maximumBy compare are respectively
equivalent to minimum and maximum (which do use min and max) only if
min and max adhere to this tie-breaking convention. Otherwise, if there
are multiple least or largest elements in a container, minimum and
maximum may not return the same one that minimumBy compare and
maximumBy compare do (though they should return something that is
equal). (This is relevant for types with non-extensional equality, like
Arg, but also in cases where the precise reference held
matters for memory-management reasons.) Unless there is a reason to deviate,
it is less confusing for implementors of Ord to respect this same
convention (as the default definitions of min and max do).
Minimal complete definition: either compare or <=.
Using compare can be more efficient for complex types.
OrdValueDefined in aeson-2.2.5.1 · Data.Aeson.Types.Internal
The ordering is total, consistent with Eq instance.
However, nothing else about the ordering is specified,
and it may change from environment to environment and version to version
of either this package or its dependencies (hashable and 'unordered-containers').
OrdBlinkSpeedDefined in ansi-terminal-types-1.1.3 · System.Console.ANSI.Types
OrdColorDefined in ansi-terminal-types-1.1.3 · System.Console.ANSI.Types
OrdColorIntensityDefined in ansi-terminal-types-1.1.3 · System.Console.ANSI.Types
OrdConsoleIntensityDefined in ansi-terminal-types-1.1.3 · System.Console.ANSI.Types
OrdConsoleLayerDefined in ansi-terminal-types-1.1.3 · System.Console.ANSI.Types
OrdUnderliningDefined in ansi-terminal-types-1.1.3 · System.Console.ANSI.Types
OrdASN1TimeTypeDefined in asn1-types-0.3.4 · Data.ASN1.Types
OrdASN1ClassDefined in asn1-types-0.3.4 · Data.ASN1.Types.Lowlevel
OrdPosDefined in attoparsec-0.14.4 · Data.Attoparsec.Internal.Types
OrdNumberDefined in attoparsec-0.14.4 · Data.Attoparsec.Number
OrdCredentialDefined in authenticate-oauth-1.7 · Web.Authenticate.OAuth
OrdOAuthVersionDefined in authenticate-oauth-1.7 · Web.Authenticate.OAuth
OrdByteArrayDefined in base-4.23.0.0 · Data.Array.Byte
Non-lexicographic ordering. This compares the lengths of
the byte arrays first and uses a lexicographic ordering if
the lengths are equal. Subject to change between major versions.
OrdEncodingDefined in basement-0.0.16 · Basement.String
OrdUTF32_InvalidDefined in basement-0.0.16 · Basement.String.Encoding.UTF32
OrdAsciiStringDefined in basement-0.0.16 · Basement.Types.AsciiString
OrdChar7Defined in basement-0.0.16 · Basement.Types.Char7
OrdFileSizeDefined in basement-0.0.16 · Basement.Types.OffsetSize
OrdAddrDefined in basement-0.0.16 · Basement.Types.Ptr
OrdWord128Defined in basement-0.0.16 · Basement.Types.Word128
OrdWord256Defined in basement-0.0.16 · Basement.Types.Word256
OrdStringDefined in basement-0.0.16 · Basement.UTF8.Base
OrdOptionsDefined in bifunctors-5.6.3 · Data.Bifunctor.TH
OrdByteOrderDefined in byteorder-1.0.4 · System.ByteOrder
OrdByteStringDefined in bytestring-0.12.2.0 · Data.ByteString.Internal.Type
OrdByteStringDefined in bytestring-0.12.2.0 · Data.ByteString.Lazy.Internal
OrdShortByteStringDefined in bytestring-0.12.2.0 · Data.ByteString.Short.Internal
Lexicographic order.
OrdConversionErrorDefined in cassava-megaparsec-2.1.1 · Data.Csv.Parser.Megaparsec.Internals
OrdByteArrayDefined in cborg-0.2.10.0 · Codec.CBOR.ByteArray
OrdSlicedByteArrayDefined in cborg-0.2.10.0 · Codec.CBOR.ByteArray.Sliced
OrdTokenTypeDefined in cborg-0.2.10.0 · Codec.CBOR.Decoding
OrdTermTokenDefined in cborg-0.2.10.0 · Codec.CBOR.FlatTerm
OrdTermDefined in cborg-0.2.10.0 · Codec.CBOR.Term
OrdSpecificityDefined in ghc-internal-10.0.0 · GHC.Internal.TH.Syntax
OrdStmtDefined in ghc-internal-10.0.0 · GHC.Internal.TH.Syntax
OrdTyLitDefined in ghc-internal-10.0.0 · GHC.Internal.TH.Syntax
OrdTySynEqnDefined in ghc-internal-10.0.0 · GHC.Internal.TH.Syntax
OrdTypeDefined in ghc-internal-10.0.0 · GHC.Internal.TH.Syntax
OrdTypeFamilyHeadDefined in ghc-internal-10.0.0 · GHC.Internal.TH.Syntax
OrdSomeCharDefined in ghc-internal-10.0.0 · GHC.Internal.TypeLits
OrdSomeSymbolDefined in ghc-internal-10.0.0 · GHC.Internal.TypeLits
OrdSomeNatDefined in ghc-internal-10.0.0 · GHC.Internal.TypeNats
OrdBoolDefined in ghc-internal-10.0.0 · GHC.Internal.Classes
OrdCharDefined in ghc-internal-10.0.0 · GHC.Internal.Classes
OrdDoubleDefined in ghc-internal-10.0.0 · GHC.Internal.Classes
IEEE 754 Double-precision type includes not only numbers, but also
positive and negative infinities and a special element called NaN
(which can be quiet or signal).
IEEE 754-2008, section 5.11 requires that if at least one of arguments of
<=, <, >, >= is NaN then the result of the comparison is False,
and instanceOrdDouble complies with this requirement. This violates
the reflexivity: both NaN<=NaN and NaN>=NaN are False.
IEEE 754-2008, section 5.10 defines totalOrder predicate. Unfortunately,
compare on Doubles violates the IEEE standard and does not define a total order.
More specifically, both compareNaNx and comparexNaN always return GT.
Thus, users must be extremely cautious when using instanceOrdDouble.
For instance, one should avoid ordered containers with keys represented by Double,
because data loss and corruption may happen. An IEEE-compliant compare is available
in fp-ieee package as TotallyOrdered newtype.
Moving further, the behaviour of min and max with regards to NaN is
also non-compliant. IEEE 754-2008, section 5.3.1 defines that quiet NaN
should be treated as a missing data by minNum and maxNum functions,
for example, minNum(NaN, 1) = minNum(1, NaN) = 1. Some languages such as Java
deviate from the standard implementing minNum(NaN, 1) = minNum(1, NaN) = NaN.
However, min / max in base are even worse: minNaN 1 is 1, but min 1 NaN
is NaN.
IEEE 754-2008 compliant min / max can be found in ieee754 package under
minNum / maxNum names. Implementations compliant with
minimumNumber / maximumNumber from a newer
IEEE 754-2019,
section 9.6 are available from fp-ieee package.
OrdFloatDefined in ghc-internal-10.0.0 · GHC.Internal.Classes
See instanceOrdDouble for discussion of deviations from IEEE 754 standard.
OrdIntDefined in ghc-internal-10.0.0 · GHC.Internal.Classes
OrdOrderingDefined in ghc-internal-10.0.0 · GHC.Internal.Classes
OrdTyConDefined in ghc-internal-10.0.0 · GHC.Internal.Classes
OrdWordDefined in ghc-internal-10.0.0 · GHC.Internal.Classes
We don't auto-derive the Ord instance because it would give an undesired ordering.
We want the keys to be sorted lexicographically:
(1) By the primary commodity of the amount.
(2) By the commodity of the cost, with no cost being first.
(3) By the unit cost, from most negative to most positive, with total costs
before unit costs.
For example, we would like the ordering to give
MixedAmountKeyNoCost X < MixedAmountKeyTotalCost XZ < MixedAmountKeyNoCost Y
OrdPeriodDefined in hledger-lib-1.52.4 · Hledger.Data.Types
OrdScientificDefined in scientific-0.3.9.0 · Data.Scientific
Scientific numbers can be safely compared for ordering. No magnitude 10^e
is calculated so there's no risk of a blowup in space or time when comparing
scientific numbers coming from untrusted sources.
OrdAbsoluteSizeDefined in shakespeare-2.2.0 · Text.Internal.CssCommon
OrdEmSizeDefined in shakespeare-2.2.0 · Text.Internal.CssCommon
OrdExSizeDefined in shakespeare-2.2.0 · Text.Internal.CssCommon
OrdPercentageSizeDefined in shakespeare-2.2.0 · Text.Internal.CssCommon
OrdPixelSizeDefined in shakespeare-2.2.0 · Text.Internal.CssCommon
OrdVarTypeDefined in shakespeare-2.2.0 · Text.Shakespeare
OrdDerefDefined in shakespeare-2.2.0 · Text.Shakespeare.Base
OrdIdentDefined in shakespeare-2.2.0 · Text.Shakespeare.Base
OrdFileTypeDefined in streaming-commons-0.2.3.1 · Data.Streaming.Filesystem
OrdHostPreferenceDefined in streaming-commons-0.2.3.1 · Data.Streaming.Network.Internal
OrdStrategyDefined in streaming-commons-0.2.3.1 · Data.Streaming.Zlib.Lowlevel
OrdHideSuccessesDefined in tasty-1.5.4 · Test.Tasty.Ingredients.ConsoleReporter
Ord (fa) => Ord (Zippyfa)Defined in semialign-1.3.1.1 · Data.Zip
Orda => Ord (Argab)Defined in base-4.23.0.0 · Data.Semigroup
Note that Arg's Ord instance has min and max implementations that
differ from the tie-breaking conventions of the default implementation of
min and max in class Ord; Arg breaks ties by favoring the first
argument in both functions.
Orda => Ord (ListNna)Defined in basement-0.0.16 · Basement.Sized.List
Orda => Ord (EnumMapka)Defined in regex-tdfa-1.3.2.6 · Data.IntMap.EnumMap2
(Ord1f, Orda) => Ord (Liftfa)Defined in transformers-0.6.3.0 · Control.Applicative.Lift
(Ord1m, Orda) => Ord (MaybeTma)Defined in transformers-0.6.3.0 · Control.Monad.Trans.Maybe
(PrimTypea, Orda) => Ord (BlockNna)Defined in basement-0.0.16 · Basement.Sized.Block
(Orda, Ord1f) => Ord (Freefa)Defined in control-monad-free-0.6.2 · Control.Monad.Free
(Orda, Ordb) => Ord (Theseab)Defined in basement-0.0.16 · Basement.These
(Orda, Ordb) => Ord (Eitherab)Defined in ghc-internal-10.0.0 · GHC.Internal.Data.Either
(Orda, Ordb) => Ord (Eitherab)Defined in strict-0.5.1 · Data.Strict.Either
(Orda, Ordb) => Ord (Theseab)Defined in strict-0.5.1 · Data.Strict.These
(Orda, Ordb) => Ord (Pairab)Defined in strict-0.5.1 · Data.Strict.Tuple
(Orda, Ordb) => Ord (Theseab)Defined in these-1.2.1 · Data.These
(Orda, Ordb) => Ord (a, b)Defined in ghc-internal-10.0.0 · GHC.Internal.Classes
(Ordk, Ordv) => Ord (Mapkv)Defined in containers-0.8 · Data.Map.Internal
(Ordk, Ordv) => Ord (HashMapkv)Defined in unordered-containers-0.2.21 · Data.HashMap.Internal
The ordering is total and consistent with the Eq instance. However,
nothing else about the ordering is specified, and it may change from
version to version of either this package or of hashable.
(Ixi, Orde) => Ord (Arrayie)Defined in ghc-internal-10.0.0 · GHC.Internal.Arr
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 would
be difficult to correct while continuing to support threadStatus.
Instances5Eq, Ord, Show, NFData, Hashable
EqThreadIdDefined in ghc-internal-10.0.0 · GHC.Internal.Conc.Sync
OrdThreadIdDefined in ghc-internal-10.0.0 · GHC.Internal.Conc.Sync
ShowThreadIdDefined in ghc-internal-10.0.0 · GHC.Internal.Conc.Sync
NFDataThreadIdDefined in deepseq-1.5.2.0 · Control.DeepSeq
HashableThreadIdDefined in hashable-1.5.1.0 · Data.Hashable.Class
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.
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 EitherStringInt 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:
Example6 expressions
>>> let s = Left "foo" :: Either String Int>>> sLeft "foo">>> let n = Right 3 :: Either String Int>>> nRight 3>>> :type ss :: Either String Int>>> :type nn :: 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:
Example4 expressions
>>> let s = Left "foo" :: Either String Int>>> let n = Right 3 :: Either String Int>>> fmap (*2) sLeft "foo">>> fmap (*2) nRight 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.
Example3 expressions
>>> 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.
Example2 expressions
>>> :{ let parseMultiple :: Either String Int parseMultiple = do x <- parseEither '1' y <- parseEither '2' return (x + y)>>> :}
Example1 expression
>>> parseMultipleRight 3
But the following should fail overall, since the first operation where
we attempt to parse 'm' as an Int will fail:
Example2 expressions
>>> :{ let parseMultiple :: Either String Int parseMultiple = do x <- parseEither 'm' y <- parseEither '2' return (x + y)>>> :}
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:
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:
The first example is a strict fold, which in practice is best performed
with foldl'.
Example1 expression
>>> 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.
Example1 expression
>>> 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:
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,
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,
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):
Example1 expression
>>> take 5 $ foldr (\i acc -> i : fmap (+3) acc) [] (repeat 1)[1,4,7,10,13]
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.
The largest element of a non-empty structure. This function is
equivalent to foldr1max, and its behavior on structures with
multiple largest elements depends on the relevant implementation of
max. For the default implementation of max (max x y = if x <= y
then y else x), structure order is used as a tie-breaker: if there are
multiple largest elements, the rightmost of them is chosen (this is
equivalent to maximumBycompare).
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:
Example1 expression
>>> maximum [1..10]10
Example1 expression
>>> maximum []*** Exception: Prelude.maximum: empty list
Example1 expression
>>> maximum Nothing*** Exception: maximum: empty structure
WARNING: This function is partial for possibly-empty structures like lists.
The least element of a non-empty structure. This function is
equivalent to foldr1min, and its behavior on structures with
multiple largest elements depends on the relevant implementation of
min. For the default implementation of min (min x y = if x <= y
then x else y), structure order is used as a tie-breaker: if there are
multiple least elements, the leftmost of them is chosen (this is
equivalent to minimumBycompare).
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:
Example1 expression
>>> minimum [1..10]1
Example1 expression
>>> minimum []*** Exception: Prelude.minimum: empty list
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:
Example1 expression
>>> null []True
Example1 expression
>>> 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).
Because we ignore the second type parameter to Const,
the Applicative instance, which has
(<*>) :: Monoid m => Const m (a -> b) -> Const m a -> Const m b
essentially turns into Monoid m => m -> m -> m, which is (<>)
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.
Example1 expression
>>> compare True FalseGT
Example1 expression
>>> 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.
Example1 expression
>>> minBound :: Int-9223372036854775808
Example1 expression
>>> minBound :: Down IntDown 9223372036854775807
All other instances of Down a behave as they do for 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 Data.Foldable.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.
Evaluate each monadic action in the structure from left to
right, and collect the results. For a version that ignores the
results see Data.Foldable.sequence_.
Examples
Basic usage:
The first two examples are instances where the input and
and output of sequence are isomorphic.
Example1 expression
>>> sequence $ Right [1,2,3,4][Right 1,Right 2,Right 3,Right 4]
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.
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).
The Haskell 2010 type for exceptions in the IO monad.
Any I/O operation may raise an IOError instead of returning a result.
For a more general type of exception, including also those that arise
in pure code, see Exception.
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 GHC.Internal.System.IO.hFlush is issued, or the handle is closed.
block-buffering: the entire buffer is written out whenever it
overflows, a GHC.Internal.System.IO.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 GHC.Internal.System.IO.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.
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.
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.
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.
Instances3NFData1, Eq, NFData
NFData1MVarDefined in deepseq-1.5.2.0 · Control.DeepSeq
Eq (MVara)Defined in ghc-internal-10.0.0 · GHC.Internal.MVar
Compares the underlying pointers.
NFData (MVara)Defined in deepseq-1.5.2.0 · Control.DeepSeq
NOTE: Only strict in the reference and not the referenced value.
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.
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 Prelude.>> and Prelude.>>= operations from the Prelude.Monad
class.
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).
>>> import GHC.Internal.Data.Ix ( index )>>> index (OtherLetter,Control) FinalQuote12>>> index (OtherLetter,Control) Format*** Exception: Error in array index
Formatting options available when displaying Amounts and MixedAmounts.
Similar to AmountStyle but lower level, not attached to amounts or commodities, and can override it in some ways.
See also hledger manual > "Amount formatting, parseability", which speaks of human, hledger, and machine output.
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).
A partition of time into one or more contiguous periods,
plus a historical period that precedes them.
Note DayPartition does not store per-period data - only the periods' start/end dates.
Instances3Eq, Ord, Show
EqDayPartitionDefined in hledger-lib-1.52.4 · Hledger.Data.DayPartition
OrdDayPartitionDefined in hledger-lib-1.52.4 · Hledger.Data.DayPartition
ShowDayPartitionDefined in hledger-lib-1.52.4 · Hledger.Data.DayPartition
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.
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.
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.
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.
Legacy behaviour, as in hledger <1.50, included to ease upgrades.
use precision inferred from the whole journal, overridable by commodity directive or -c.
Display precision is also transaction balancing precision; increasing it can break journal reading.
Some valid journals are rejected until commodity directives are added.
Small unbalanced remainders can be hidden, and in accounts that are never reconciled, can accumulate over time.
Simpler, more robust behaviour, as in Ledger: use precision inferred from the transaction.
Display precision and transaction balancing precision are independent; display precision never affects journal reading.
Valid journals from ledger or beancount are accepted without needing commodity directives.
Every imbalance in a transaction is visibly accounted for in that transaction's journal entry.
An account within a hierarchy, with references to its parent
and subaccounts if any, and with per-report-period data of type a.
Only the name is required; the other fields may or may not be present.
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.
Display styles for amounts - things which can be detected during parsing, such as
commodity side and spacing, digit group marks, decimal mark, number of decimal digits etc.
Every Amount has an AmountStyle.
After amounts are parsed from the input, for each Commodity a standard style is inferred
and then used when displaying amounts in that commodity.
Related to AmountFormat but higher level.
"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 that amount's display precision.
Instances9Eq, Ord, Read, Show, Generic, NFData, …
EqAmountStyleDefined in hledger-lib-1.52.4 · Hledger.Data.Types
OrdAmountStyleDefined in hledger-lib-1.52.4 · Hledger.Data.Types
ReadAmountStyleDefined in hledger-lib-1.52.4 · Hledger.Data.Types
ShowAmountStyleDefined in hledger-lib-1.52.4 · Hledger.Data.Types
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 that's useful in "balance" reports:
subaccount-exclusive and -inclusive amounts,
typically representing either a balance change or an end balance;
and a count of postings.
The cost basis of an individual lot - some quantity of an asset acquired at a given date and time.
This can represent a definite cost basis, which must have a cost and date; the label is optional.
Or it can represent a cost basis matcher for selecting lots.
Note: cost is always stored as a per-unit cost, even if the user specified total cost with {{}}.
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.
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].
A journal, containing general ledger transactions; also directives and various other things.
This is hledger's main data model.
During parsing, it is used as the type alias ParsedJournal.
The jparse* fields are mainly used during parsing and included here for convenience.
The list fields described as "in parse order" are usually reversed for efficiency during parsing.
After parsing, "journalFinalise" converts ParsedJournal to a finalised Journal,
which has all lists correctly ordered, and much data inference and validation applied.
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)
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 "" or "-" can be seen
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
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.
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
A general container for storing data values associated with zero or more
contiguous report (sub)periods, and with the (open ended) pre-report period.
The report periods are typically all the same length, but need not be.
Report periods are represented only by their start dates, used as the keys of a Map.
The Semigroup instance for PeriodData simply takes the union of
keys in the date map section. This may not be the result you want if the
keys are not identical.
Monoida => Monoid (PeriodDataa)Defined in hledger-lib-1.52.4 · Hledger.Data.PeriodData · orphan
When this posting has been transformed in some way
(eg its amount or cost 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).
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.
"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.
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 a numeric offset relative to the reference date:
(last|this|next) (day|week|month|quarter|year), where "this" means the period
containing the reference date.
Or, (last|this|next) weekdayname, where "this" "next".
Or, (last|this|next) monthname, where "this" means the previous 1st if in that month,
otherwise the start of the next occurrence of that month.
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.
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.
Which operation to perform on conversion transactions.
(There was also an "infer equity postings" operation, but that is now done
earlier, in journal finalisation.)
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.
report interval extracted from a date: query
| QueryOptCostBasis -- ^ show amounts converted to cost where possible
| QueryOptDate2 -- ^ show secondary dates instead of primary dates
Instances2Eq, Show
EqQueryOptDefined in hledger-lib-1.52.4 · Hledger.Query
ShowQueryOptDefined in hledger-lib-1.52.4 · Hledger.Query
A hledger journal reader is a storage format name,
a list of file extensions assumed to be in this format,
and an IO action that reads data in this format, returning a Journal.
The journal parser used by the latter is also stored separately for direct use
by the journal reader's includedirectivep to parse included files.
The type variable m is needed for this parser.
Lately it requires an InputOpts, basically to support --old-timeclock.
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.
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
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.
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.
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:
Example5 expressions
>>> import Lens.Micro (set)>>> _rsQuery <$> setEither querystring ["assets"] defreportspecRight (Acct (RegexpCI "assets"))>>> _rsQuery <$> setEither querystring ["(assets"] defreportspecLeft "This regular expression is invalid or unsupported, please correct it:\n(assets">>> _rsQuery $ set querystring ["assets"] defreportspecAcct (RegexpCI "assets")>>> _rsQuery $ set period (MonthPeriod 2021 08) defreportspecDate DateSpan 2021-08
XXX testing error output isn't working since adding color to it:
> import System.Environment
> setEnv NO_COLOR "1" >> return (_rsQuery $ set querystring ["(assets"] defreportspec)
*** Exception: Error: Updating ReportSpec failed: try using overEither instead of over or setEither instead of set
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.
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.
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.
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.
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.)
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.
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.
Whether ghc-debug support is included in this build, and if so, how it will behave.
When hledger is built with the ghcdebug cabal flag (off by default, because of extra deps),
it can listen (on unix ?) for connections from ghc-debug clients like ghc-debug-brick,
for pausing/resuming the program and inspecting memory usage and profile information.
With a ghc-debug-supporting build, ghc-debug can be enabled by running hledger with
a negative --debug level. There are three different modes:
--debug=-1 - run normally (can be paused/resumed by a ghc-debug client),
--debug=-2 - pause and await client commands at program start (not useful currently),
--debug=-3 - pause and await client commands at program end.
A type representing "final" parse errors that cannot be backtracked
from and are guaranteed to halt parsing. The anti-backtracking
behaviour is implemented by an ExceptT layer in the parser's monad
stack, using this type as the ExceptT error type.
We have three goals for this type:
(1) it should be possible to convert any parse error into a "final"
parse error,
(2) it should be possible to take a parse error thrown from an include
file and re-throw it in the context of the parent file, and
(3) the pretty-printing of "final" parse errors should be consistent
with that of ordinary parse errors, but should also report the stack of
parent files when errors are thrown from included files.
In order to pretty-print a "final" parse error (goal 3), it must be
bundled with include filepaths and its full source text. When a "final"
parse error is thrown from within a parser, we do not have access to
the full source, so we must hold the parse error (FinalParseError)
until it can be combined with the full source (and any parent file paths)
by the parser's caller (FinalParseErrorBundle).
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.
A fragment of source suitable for "re-parsing". The purpose of this
data type is to preserve the content and source position of the excerpt
so that parse errors raised during "re-parsing" may properly reference
the original source.
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.
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.
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.
Instances3Eq, Show, IsString
EqCmdSpecDefined in process-1.6.30.0 · System.Process.Common
ShowCmdSpecDefined in process-1.6.30.0 · System.Process.Common
IsStringCmdSpecDefined in process-1.6.30.0 · System.Process.Common
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.
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.
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
Instances2Eq, Show
EqCreateProcessDefined in process-1.6.30.0 · System.Process.Common
ShowCreateProcessDefined in process-1.6.30.0 · System.Process.Common
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.
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.
Instances2Eq, Show
EqStdStreamDefined in process-1.6.30.0 · System.Process.Common
ShowStdStreamDefined in process-1.6.30.0 · System.Process.Common
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.
Deprecated. This class or type seems dubious. If you have a good use case for it, please create an issue for tasty. Otherwise, it may be removed in a future version.
Allows the extension of the assertion mechanism.
Since an Assertion can be a sequence of Assertions and IO actions,
there is a fair amount of flexibility of what can be achieved. As a rule,
the resulting Assertion should be the body of a TestCase or part of
a TestCase; it should not be used to assert multiple, independent
conditions.
If more complex arrangements of assertions are needed, Test and
Testable should be used.
Deprecated. This class or type seems dubious. If you have a good use case for it, please create an issue for tasty. Otherwise, it may be removed in a future version.
The result of an assertion that hasn't been evaluated yet.
Most test cases follow the following steps:
Do some processing or an action.
Assert certain conditions.
However, this flow is not always suitable. AssertionPredicate allows for
additional steps to be inserted without the initial action to be affected
by side effects. Additionally, clean-up can be done before the test case
has a chance to end. A potential work flow is:
Write data to a file.
Read data from a file, evaluate conditions.
Clean up the file.
Assert that the side effects of the read operation meet certain conditions.
Assert that the conditions evaluated in step 2 are met.
DataTextDefined in text-2.1.4 · Data.Text · orphan
This instance preserves data abstraction at the cost of inefficiency.
We omit reflection services for the sake of data abstraction.
This instance was created by copying the updated behavior of
Data.Set.Set and Data.Map.Data.Map.Map. If you
feel a mistake has been made, please feel free to submit
improvements.
EnumDayOfWeekDefined in time-1.16.0.1 · Data.Time.Calendar.Week
"Circular", so for example [Tuesday ..] gives an endless sequence.
Also: fromEnum gives [1 .. 7] for [Monday .. Sunday], and toEnum performs mod 7 to give a cycle of days.
EqDayOfWeekDefined in time-1.16.0.1 · Data.Time.Calendar.Week
DataDayOfWeekDefined in time-1.16.0.1 · Data.Time.Calendar.Week
OrdDayOfWeekDefined in time-1.16.0.1 · Data.Time.Calendar.Week
ReadDayOfWeekDefined in time-1.16.0.1 · Data.Time.Calendar.Week
ShowDayOfWeekDefined in time-1.16.0.1 · Data.Time.Calendar.Week
IxDayOfWeekDefined in time-1.16.0.1 · Data.Time.Calendar.Week
GenericDayOfWeekDefined in time-1.16.0.1 · Data.Time.Calendar.Week
NFDataDayOfWeekDefined in time-1.16.0.1 · Data.Time.Calendar.Week
HashableDayOfWeekDefined in time-compat-1.9.9 · Data.Time.Orphans · orphan
FormatTimeDayOfWeekDefined in time-1.16.0.1 · Data.Time.Format.Format.Instances · orphan
ParseTimeDayOfWeekDefined in time-1.16.0.1 · Data.Time.Format.Parse.Instances · orphan
FromJSONDayOfWeekDefined in aeson-2.2.5.1 · Data.Aeson.Types.FromJSON
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.
EnumDiffTimeDefined in time-1.16.0.1 · Data.Time.Clock.Internal.DiffTime
EqDiffTimeDefined in time-1.16.0.1 · Data.Time.Clock.Internal.DiffTime
FractionalDiffTimeDefined in time-1.16.0.1 · Data.Time.Clock.Internal.DiffTime
DataDiffTimeDefined in time-1.16.0.1 · Data.Time.Clock.Internal.DiffTime
NumDiffTimeDefined in time-1.16.0.1 · Data.Time.Clock.Internal.DiffTime
OrdDiffTimeDefined in time-1.16.0.1 · Data.Time.Clock.Internal.DiffTime
ReadDiffTimeDefined in time-1.16.0.1 · Data.Time.Clock.Internal.DiffTime
RealDiffTimeDefined in time-1.16.0.1 · Data.Time.Clock.Internal.DiffTime
RealFracDiffTimeDefined in time-1.16.0.1 · Data.Time.Clock.Internal.DiffTime
ShowDiffTimeDefined in time-1.16.0.1 · Data.Time.Clock.Internal.DiffTime
NFDataDiffTimeDefined in time-1.16.0.1 · Data.Time.Clock.Internal.DiffTime
HashableDiffTimeDefined in time-compat-1.9.9 · Data.Time.Orphans · orphan
FormatTimeDiffTimeDefined in time-1.16.0.1 · Data.Time.Format.Format.Instances · orphan
ParseTimeDiffTimeDefined in time-1.16.0.1 · Data.Time.Format.Parse.Instances · orphan
FromJSONDiffTimeDefined in aeson-2.2.5.1 · Data.Aeson.Types.FromJSON
This instance includes a bounds check to prevent maliciously
large inputs to fill up the memory of the target system. You can
newtype Scientific and provide your own instance using
withScientific if you want to allow larger inputs.
ToJSONDiffTimeDefined in aeson-2.2.5.1 · Data.Aeson.Types.ToJSON
LiftDiffTimeDefined in time-1.16.0.1 · Data.Time.Clock.Internal.DiffTime
This is a length of time, as measured by UTC.
It has a precision of one picosecond (10^-12 s).
Conversion functions such as fromInteger and realToFrac will treat it as seconds.
For example, (0.010 :: NominalDiffTime) corresponds to 10 milliseconds.
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.
This instance includes a bounds check to prevent maliciously
large inputs to fill up the memory of the target system. You can
newtype Scientific and provide your own instance using
withScientific if you want to allow larger inputs.
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.
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.
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.
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.
The name of the zone, typically a three- or four-letter acronym.
Instances13Eq, Data, Ord, Read, Show, Generic, …
EqTimeZoneDefined in time-1.16.0.1 · Data.Time.LocalTime.Internal.TimeZone
DataTimeZoneDefined in time-1.16.0.1 · Data.Time.LocalTime.Internal.TimeZone
OrdTimeZoneDefined in time-1.16.0.1 · Data.Time.LocalTime.Internal.TimeZone
ReadTimeZoneDefined in time-1.16.0.1 · Data.Time.Format.Parse · orphan
This only works for ±HHMM format,
single-letter military time-zones,
and these time-zones: "UTC", "UT", "GMT", "EST", "EDT", "CST", "CDT", "MST", "MDT", "PST", "PDT",
per RFC 822 section 5.
ShowTimeZoneDefined in time-1.16.0.1 · Data.Time.LocalTime.Internal.TimeZone
This only shows the time zone name, or offset if the name is empty.
GenericTimeZoneDefined in time-1.16.0.1 · Data.Time.LocalTime.Internal.TimeZone
NFDataTimeZoneDefined in time-1.16.0.1 · Data.Time.LocalTime.Internal.TimeZone
HashableTimeZoneDefined in time-compat-1.9.9 · Data.Time.Orphans · orphan
FormatTimeTimeZoneDefined in time-1.16.0.1 · Data.Time.Format.Format.Instances · orphan
ParseTimeTimeZoneDefined in time-1.16.0.1 · Data.Time.Format.Parse.Instances · orphan
ISO8601TimeZoneDefined in time-1.16.0.1 · Data.Time.Format.ISO8601
±hh:mm [ISO 8601:2004(E) sec. 4.2.5.1 extended format]
LiftTimeZoneDefined in time-1.16.0.1 · Data.Time.LocalTime.Internal.TimeZone
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.
DataZonedTimeDefined in time-1.16.0.1 · Data.Time.LocalTime.Internal.ZonedTime
ReadZonedTimeDefined in time-1.16.0.1 · Data.Time.Format.Parse · orphan
This only works for a zonedTimeZone in ±HHMM format,
single-letter military time-zones,
and these time-zones: "UTC", "UT", "GMT", "EST", "EDT", "CST", "CDT", "MST", "MDT", "PST", "PDT",
per RFC 822 section 5.
ShowZonedTimeDefined in time-1.16.0.1 · Data.Time.LocalTime.Internal.ZonedTime
For the time zone, this only shows the name, or offset if the name is empty.
GenericZonedTimeDefined in time-1.16.0.1 · Data.Time.LocalTime.Internal.ZonedTime
NFDataZonedTimeDefined in time-1.16.0.1 · Data.Time.LocalTime.Internal.ZonedTime
FormatTimeZonedTimeDefined in time-1.16.0.1 · Data.Time.Format.Format.Instances · orphan
ParseTimeZonedTimeDefined in time-1.16.0.1 · Data.Time.Format.Parse.Instances · orphan
ISO8601ZonedTimeDefined in time-1.16.0.1 · Data.Time.Format.ISO8601
yyyy-mm-ddThh:mm:ss[.ss]±hh:mm [ISO 8601:2004(E) sec. 4.3.2 extended format]
FromJSONZonedTimeDefined in aeson-2.2.5.1 · Data.Aeson.Types.FromJSON
The first space may instead be a T, and the second space is
optional. The Z represents UTC. The Z may be replaced with a
time zone offset of the form +0000 or -08:00, where the first
two digits are hours, the : is optional and the second two digits
(also optional) are minutes.
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.
Lift a semigroup into Maybe forming a Monoid according to
http://en.wikipedia.org/wiki/Monoid: "Any semigroup S may be
turned into a monoid simply by adjoining an element e not in S
and defining e*e = e and e*s = s = s*e for all s ∈ S."
Since 4.11.0: constraint on inner a value generalised from
Monoid to Semigroup.
SingKinda => SingKind (Maybea)Defined in ghc-internal-10.0.0 · GHC.Internal.Generics
NFDataa => NFData (Maybea)Defined in deepseq-1.5.2.0 · Control.DeepSeq
Prettya => Pretty (Maybea)Defined in pretty-1.1.3.6 · Text.PrettyPrint.Annotated.HughesPJClass
Prettya => Pretty (Maybea)Defined in pretty-1.1.3.6 · Text.PrettyPrint.HughesPJClass
Finitea => Finite (Maybea)Defined in random-1.3.1 · System.Random.GFinite
Character literals in Haskell are single-quoted: 'Q', 'Я' or 'Ω'.
To represent a single quote itself use '\'', and to represent a backslash
use '\\'. The full grammar can be found in the section 2.6 of the
Haskell 2010 Language Report.
To specify a character by its code point one can use decimal, hexadecimal
or octal notation: '\65', '\x41' and '\o101' are all alternative forms
of 'A'. The largest code point is '\x10ffff'.
There is a special escape syntax for ASCII control characters:
In Haskell, lists are one of the most important data types as they are
often used analogous to loops in imperative programming languages.
These lists are singly linked, which makes them unsuited for operations
that require \mathcal{O}(1) access. Instead, they are intended to
be traversed.
You can use List a or [a] in type signatures:
length :: [a] -> Int
or
length :: List a -> Int
They are fully equivalent, and List a will be normalised to [a].
Usage
Lists are constructed recursively using the right-associative constructor operator (or cons)
(:) :: a -> [a] -> [a], which prepends an element to a list,
and the empty list [].
Lists can also be constructed using list literals
of the form [x_1, x_2, ..., x_n]
which are syntactic sugar and, unless -XOverloadedLists is enabled,
are translated into uses of (:) and []
String literals, like "I 💜 hs", are translated into
Lists of characters, ['I', ' ', '💜', ' ', 'h', 's'].
Implementation
Internally and in memory, all the above are represented like this,
with arrows being pointers to locations in memory.
╭───┬───┬──╮ ╭───┬───┬──╮ ╭───┬───┬──╮ ╭────╮
│(:)│ │ ─┼──>│(:)│ │ ─┼──>│(:)│ │ ─┼──>│ [] │
╰───┴─┼─┴──╯ ╰───┴─┼─┴──╯ ╰───┴─┼─┴──╯ ╰────╯
v v v
1 2 3