formatting-7.2.0: Combinator-based type-safe formatting (like printf() or FORMAT)

Copyright | (c) 2013 Chris Done 2013 Shachaf Ben-Kiki
License | BSD3
Maintainer | alex@farfromthere.net
Stability | experimental
Portability | GHC
Safe Haskell | None
Language | Haskell2010

Formatting

Contents

- Top-level functions
- Formatting library

Description

Combinator-based type-safe formatting (like printf() or FORMAT) for Text.

Example:

    >>> format ("Person's name is " % text % ", age is " % hex) "Dave" 54
    "Person's name is Dave, age is 36"

See Formatting.Formatters for a list of formatters. See Formatting.Combinators for a list of formatting combinators, for combining and altering formatters.

Synopsis

- data Format r a
- (%) :: Format r a -> Format r' r -> Format r' a
- (%+) :: Format r a -> Format r' r -> Format r' a
- (%.) :: Format r (Builder -> r') -> Format r' a -> Format r a
- (<%+>) :: Format r (a -> r) -> Format r (a -> r) -> Format r (a -> r)
- now :: Builder -> Format r r
- later :: (a -> Builder) -> Format r (a -> r)
- mapf :: (a -> b) -> Format r (b -> t) -> Format r (a -> t)
- runFormat :: Format r a -> (Builder -> r) -> a
- format :: Format Text a -> a
- sformat :: Format Text a -> a
- bprint :: Format Builder a -> a
- bformat :: Format Builder a -> a
- fprint :: MonadIO m => Format (m ()) a -> a
- fprintLn :: MonadIO m => Format (m ()) a -> a
- hprint :: MonadIO m => Handle -> Format (m ()) a -> a
- hprintLn :: MonadIO m => Handle -> Format (m ()) a -> a
- formatToString :: Format String a -> a
- formatted :: FromBuilder t => (t -> o) -> Format o a -> a
- module Formatting.Formatters
- module Formatting.Combinators

# Documentation

data Format r a Source #

A formatter. When you construct formatters the first type parameter, `r`, will remain polymorphic. The second type parameter, `a`, will change to reflect the types of the data that will be formatted. For example, in

    myFormat :: Format r (Text -> Int -> r)
    myFormat = "Person's name is " % text % ", age is " % hex

the first type parameter remains polymorphic, and the second type parameter is `Text -> Int -> r`, which indicates that it formats a `Text` and an `Int`.

When you run the `Format`, for example with `format`, you provide the arguments and they will be formatted into a string.

    > format ("Person's name is " % text % ", age is " % hex) "Dave" 54
    "Person's name is Dave, age is 36"

#### Instances

Instances details

Category Format Source # | The same as (%). At present using `Category` has an import overhead, but one day it might be imported as standard.
Instance details Defined in Formatting.Internal Methods id :: Format a a Source # (.) :: Format b c -> Format a b -> Format a c Source #

Functor (Format r) Source #

This can be used almost like contramap, e.g:

    formatter :: Format r (b -> r)
    formatter = _

    adapter :: a -> b
    adapter = _

    adapted :: Format r (a -> r)
    adapted = fmap (. adapter) formatter

Instance details Defined in Formatting.Internal Methods fmap :: (a -> b) -> Format r a -> Format r b Source # (<$) :: a -> Format r b -> Format r a Source #
Monoid (Format r (a -> r)) Source # | Useful instance for applying two formatters to the same input argument. For example: `format (year <> "/" % month) now` will yield `"2015/01"`.
Instance details Defined in Formatting.Internal Methods mempty :: Format r (a -> r) Source # mappend :: Format r (a -> r) -> Format r (a -> r) -> Format r (a -> r) Source # mconcat :: [Format r (a -> r)] -> Format r (a -> r) Source #
Semigroup (Format r (a -> r)) Source # |
Instance details Defined in Formatting.Internal Methods (<>) :: Format r (a -> r) -> Format r (a -> r) -> Format r (a -> r) Source # sconcat :: NonEmpty (Format r (a -> r)) -> Format r (a -> r) Source # stimes :: Integral b => b -> Format r (a -> r) -> Format r (a -> r) Source #
a ~ r => IsString (Format r a) Source # | Useful instance for writing format string. With this you can write `"Foo"` instead of `now "Foo!"`.
Instance details Defined in Formatting.Internal Methods fromString :: String -> Format r a Source #

(%) :: Format r a -> Format r' r -> Format r' a infixr 9 Source #

Concatenate two formatters.

`formatter1 % formatter2` is a formatter that accepts arguments for `formatter1` and `formatter2` and concatenates their results. For example

    format1 :: Format r (Text -> r)
    format1 = "Person's name is " % text

    format2 :: Format r r
    format2 = ", "

    format3 :: Format r (Int -> r)
    format3 = "age is " % hex

    myFormat :: Format r (Text -> Int -> r)
    myFormat = format1 % format2 % format3

Notice how the argument types of `format1` and `format3` are gathered into the type of `myFormat`.

(This is actually the composition operator for `Format`s `Category` instance, but that is (at present) inconvenient to use with regular Prelude. So this function is provided as a convenience.)

(%+) :: Format r a -> Format r' r -> Format r' a infixr 9 Source #

Concatenate two formatters with a space in between.

    >>> :set -XOverloadedStrings
    >>> format (int %+ "+" %+ int %+ "=" %+ int) 2 3 5
    "2 + 3 = 5"

(%.) :: Format r (Builder -> r') -> Format r' a -> Format r a infixr 8 Source #

Function compose two formatters. Will feed the result of one formatter into another.

(<%+>) :: Format r (a -> r) -> Format r (a -> r) -> Format r (a -> r) Source #

Like `(<>)` except put a space between the two formatters. For example: `format (year %+ month %+ dayOfMonth) now` will yield `"2022 06 06"`

now :: Builder -> Format r r Source #

Don't format any data, just output a constant `Builder`.

later :: (a -> Builder) -> Format r (a -> r) Source #

Format a value of type `a` using a function of type `a -> `Builder``. For example, `later (f :: Int -> Builder)` produces `Format r (Int -> r)`.

mapf :: (a -> b) -> Format r (b -> t) -> Format r (a -> t) Source #

Functorial map over a formatter's input. Example: `format (mapf (drop 1) string) "hello"`

# Top-level functions

runFormat :: Format r a -> (Builder -> r) -> a Source #

format :: Format Text a -> a Source #

Run the formatter and return a lazy `Text` value.

sformat :: Format Text a -> a Source #

Run the formatter and return a strict `Text` value.

bprint :: Format Builder a -> a Source #

Run the formatter and return a `Builder` value.

bformat :: Format Builder a -> a Source #

Run the formatter and return a `Builder` value.

This is a newer synonym for `bprint`, following the naming convention set by `format` and `sformat`.

fprint :: MonadIO m => Format (m ()) a -> a Source #

Run the formatter and print out the text to stdout.

fprintLn :: MonadIO m => Format (m ()) a -> a Source #

Run the formatter and print out the text to stdout, followed by a newline.

hprint :: MonadIO m => Handle -> Format (m ()) a -> a Source #

Run the formatter and put the output onto the given `Handle`.

hprintLn :: MonadIO m => Handle -> Format (m ()) a -> a Source #

Run the formatter and put the output and a newline onto the given `Handle`.

formatToString :: Format String a -> a Source #

Run the formatter and return a list of characters.

formatted :: FromBuilder t => (t -> o) -> Format o a -> a Source #

Makes it easy to add formatting to any api that is expecting a builder, a strict or lazy text, or a string. It is essentially (flip runFormat), but with a more generous type due to the typeclass.

For example: >>> formatted TL.putStr ("x is: " % int % "n") 7 x is: 7 >>> formatted T.putStr ("x is: " % int % "n") 7 x is: 7 >>> formatted (id `TL.Text) ("x is: " % int % "n") 7 "x is: 7n" >>> formatted (id` T.Text) ("x is: " % int % "n") 7 "x is: 7n"

# Formatting library

module Formatting.Formatters

module Formatting.Combinators