!'@      !"#$%&'()*+,-./0123456789:;<=>?Safe@ABCDEFGSafe vformat"A data type indicates an arg errorvformat'Can not find argument for the given keyvformat8The field format descriptor does not match the argumentvformatERaises an error with a vformat-specific prefix on the message string.vformatCalls / to indicate an arg key error for a given type.vformatCalls 2 to indicate an arg format error for a given type. HIJKSafevformat,A data type indicates key of format argumentThe key syntax - key -> [(int | chars) {"!" (int | chars)}] ySince the "!" is used to seprate keys, if you need to include a "!" in a named key, it can be escaped by doubling "!!". Note: See Format0 to learn more about syntax description languageExamplesread "0" :: ArgKeyread "country" :: ArgKeyread "coun!!try" :: ArgKeyread "country!name" :: ArgKey'read "country!cities!10!name" :: ArgKeyvformatURefers to a top-level positional argument or an element in an list-like data type.vformatGRefers to a top-level named argument or a field of a record data type. vformatFor  Nest k1 k2, k1 refers to a top-level argument or an attribute (element or field) of a data type, k2 refers an attribute of the data referenced by k1. vformat3Extract the topmost indexed or named key from a key%topKey (read "k1!k2!k3") == Name "k1"True#topKey (read "name") == Name "name"True topKey (read "123") == Index 123True topKey mempty%*** Exception: vformat: empty arg key vformat2Remove the topmost indexed or named key from a key(popKey (read "k1!k2!k3") == read "k2!k3"TruepopKey (read "name") == memptyTruepopKey (read "123") == memptyTrue popKey mempty%*** Exception: vformat: empty arg key  Safe"#W vformat0A data type indicates how to format an argument.The format syntax & fmt -> [[pad] align][sign]["#"]["0"][width][sep]["." precision][specs] pad -> char align -> "<" | ">" | "^" | "=" sign -> "+" | "-" | " " width -> int | ("{" key "}") sep -> "_" | "," precision -> int | ("{" key "}") specs -> chars key -> <see > #9 will cause the "alternate form" to be used for integers.@The alternate format is defined differently for different types.add 0b prefix for binaryadd 0o prefix for octaladd 0x prefix for hexadecimalwith$ indicates minimum with of the field>If omitted, the field width will be determined by the content.When align is omitted, preceding width by a zero character enables sign-aware zero-padding for numbers. This is equivalent to a pad of 0 with an align of =. precision indicates how many digits should be displayed after the decimal point for a floating point number, or maximum width for other types.When precision is omitted2preceding dot is present, indicates precision is 0preceding dot is omitted too, indicates precision not set, default value (i.e. 6 for floating point numbers, 0 for others) will be used.specs! indicates type specified optionsuWhen specs is omitted, the default specs will be used. The default specs is defined differently from different types.Examplesread "*<30s" :: ArgFmtread "<10.20s" :: ArgFmtread "0=10_.20d" :: ArgFmtread "#010_.20b" :: ArgFmt String specs  s default s  Integer specs D b binary format integer c char point (L will be trasformed by  first) d decimal format integer o octal format integer x hex format integer (use lower-case letters) X hex format integer (use upper-case letters) default d Floating point number specs ( e exponent notation, see M2 E same as "e", but use upper-case E8 as separator f fixed-point notation see Nk F same as "f", but converts nan to NAN and inf to INF g general format, see O2 G same as "g", but use upper-case E as separator and converts nan to NAN and inf to INF % percentage, same as "f" except multiplies 100 first and followed by a percent sign default g See 1 to learn how to define specs for your own types.vformatEWhen reading from a string, different strings may produce the same  F, this field keeps the original string here in case it is use later.vformat&A data type indicates number separatore.g. 20,200,101 20_200_202vformatDon't separate numbervformatUse dash as number separatorvformatUse comma as number separatorvformat/A data type indicates how to show number's signvformatNot specified, equivalent to  for signed numbers.vformatCSign should be used for both positive as well as negative numbers.vformat-Sign should be used only for negative numbers vformatZA leading space should be used on positive numbers, and a minus sign on negative numbers.!vformat,A data type indicates how to align arguments"vformatNot specified, equivalent to #% unless number's sign aware enabled.#vformatCForces the argument to be left-aligned within the available space.$vformatAForces the field to be right-aligned within the available space.%vformat<Forces the field to be centered within the available space.&vformatbNumber specified, forces the padding to be placed after the sign (if any) but before the digits.'vformatPretty showing  Note: Don't create   manually, P from a string, see  .  !"#$%&'QR Safer(vformat A variant of )', it transforms all argument's key to Nest (Index 0) key)vformat%A data type indicates a format stringFormat string contains "replacement fields" surrounded by curly braces {}. Anything that is not contained in braces is considered literal text, which is copied unchanged to the output. If you need to include a brace character in the literal text, it can be escaped by doubling {{ and }}.Format string syntax = format -> {chars | ("{" [key][":"fmt] "}")} key -> <see > fmt -> <see  > [Note: This library use a description language to describe syntax, see next section.Note: A key can be omitted only if there is no explict index key before it, it will be automatically caculated and inserted to the format string according to its position in the omitted key sequence.Examples1"I like {coffee}, I drink it everyday." :: Format+"{no:<20} {name:<20} {age}" :: Format2"{{\"no\": {no}, \"name\": \"{name}\"}}" :: FormatSyntax description language8A syntax expr may contain a list of fields as followings  identifier identifier of an expr <description> use natural language as an expr -> use right hand expr to describe identifier () a required field, may be omitted [] an optional field {} repeat any times of the field | logical or, choice between left and right "" literal text Built-in exprs M char -> <any character> chars -> {char} int -> <integer without sign> (ST)UVWXY Safe "#8=>?UV*vformat3A type represents the top-level named key argument.,vformat6A typeclass provides the variable arguments magic for format. vformat0Options that specify how to format your datatypeOOptions can be set using record syntax on defaultOptions with the fields below.0 vformatVTypeclass for types that can be used as the key of a map-like or list-like container.For example, since Z and [ datatypes are instance of 0 and \ is an instance of 2 , we can format a value of type ] Z \.2vformatTypeclass of formatable values.The 3U method takes a value, a key and a field format descriptor and either fails due to a 8 or produce a string as the result. There is a default 3 for ^ instances, which applies 5 to 6./There are two reasons may cause formatting fail (Can not find argument for the given key.8The field format descriptor does not match the argument.Extending to new types{Those format functions can be extended to format types other than those provided by default. This is done by instantiating 2.Examples {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-} import Control.Exception import GHC.Generics import Text.Format -- Manually extend to () instance FormatArg () where formatArg x k fmt@(ArgFmt{fmtSpecs="U"}) = let fmt' = fmt{fmtSpecs = ""} in formatArg (show x) k fmt' formatArg _ _ _ = Left $ toException ArgFmtError -- Use default generic implementation for type with nullary data constructors. data Color = Red | Yellow | Blue deriving Generic instance FormatArg Color -- Use default generic implementation for type with non-nullary data constructor. data Triple = Triple String Int Double deriving Generic instance FormatArg Triple -- Use default generic implementation for type using record syntax. data Student = Student { no :: Int , name :: String , age :: Int } deriving Generic instance FormatArg Student -- Customize field names data Book = Book { bookName :: String , bookAuthor :: String , bookPrice :: Double } instance FormatArg Book where formatArg x k fmt | k == mempty = return $ format1 "{name} {author} {price:.2f}" x | k == Name "name" = formatArg (bookName x) mempty fmt | k == Name "author" = formatArg (bookAuthor x) mempty fmt | k == Name "price" = formatArg (bookPrice x) mempty fmt | otherwise = Left $ toException $ ArgKeyError -- A better way to customize field names -- instance FormatArg Book where -- formatArg = genericFormatArg $ -- defaultOptions { fieldLabelModifier = drop 4 } main :: IO () main = do putStrLn $ format "A unit {:U}" () putStrLn $ format "I like {}." Blue putStrLn $ format "Triple {0!0} {0!1} {0!2}" $ Triple "Hello" 123 pi putStrLn $ format1 "Student: {no} {name} {age}" $ Student 1 "neo" 30 putStrLn $ format "A book: {}" $ Book "Math" "nobody" 99.99 putStrLn $ format1 "Book: {name}, Author: {author}, Price: {price:.2f}" $ Book "Math" "nobody" 99.99 Note: Since v0.12.0,  FormatTime instance has been remove, use  /http://hackage.haskell.org/package/vformat-time vformat-time instead._vformatThis method is used to get the key of a top-level argument. Top-level argument means argument that directly passed to format functions (format, format1).5 vformatDefault format options . { / = id } 6 vformatA configurable generic 4 creator.7 vformatFormatter for string values8 vformatFormatter for L values9 vformatFormatter for ` values: vformatFormatter for a values; vformatFormatter for b values< vformatFormatter for c values= vformat+Use a default specs for the given formatter*+,-.d/0123e_456789:;<=*6+6(c) 2019 Version CloudBSD3Jorah Gao <jorah@version.cloud> experimentalportableSafe#>vformatEFormat a variable number of arguments with Python-style format string*format "{:s}, {:d}, {:.4f}" "hello" 123 pi"hello, 123, 3.1416"-format "{1:s}, {0:d}, {2:.4f}" 123 "hello" pi"hello, 123, 3.1416"4format "{:s} {:d} {pi:.4f}" "hello" 123 ("pi" := pi)"hello, 123, 3.1416"See )* to learn more about format string syntax.See 2: to learn how to derive FormatArg for your own data types.?vformat A variant of >', it takes only one positional argument:set -XDeriveGenericimport GHC.Generics7data Triple = Triple String Int Double deriving Genericinstance FormatArg Triple:format "{0!0:s} {0!1:d} {0!2:.4f}" $ Triple "hello" 123 pi"hello, 123, 3.1416"5format1 "{0:s} {1:d} {2:.4f}" $ Triple "hello" 123 pi"hello, 123, 3.1416"@   !"#$%&'()*+,-./0123456789:;<=>?@>?2301,-.5/64)(  '!"#$%& *+789:;<=f    !"#$%&'()*+,-./01 2 3 4 4 5 6 7 8 9 :  ; < = > ? @ A B C D EFGHIJKLMNOPQRSTUVWXVWYVWZV[\]^ 2 _ 3 ` a b cVdeVfgTUhijkVlm nTUoTUpqrsVtu 7 vw'vformat-0.13.0.0-IXTTdMSfvMiIrkkZxkL54n Text.Format Paths_vformatText.Format.ErrorText.Format.ArgKeyText.Format.ArgFmtCharord FormatArgText.Format.FormatText.Format.ClassArgError ArgKeyError ArgFmtErrorvferror errorArgKey errorArgFmtArgKeyIndexNameNesttopKeypopKeyArgFmtfmtAlignfmtPadfmtSign fmtAlternate fmtSignAwarefmtWidth fmtNumSep fmtPrecisionfmtSpecsfmtRaw FmtNumSep NumSepNone NumSepDash NumSepCommaFmtSignSignNoneSignPlus SignMinus SignSpaceFmtAlign AlignNone AlignLeft AlignRight AlignCenter AlignSign prettyArgFmtFormat1Format:= FormatTypesfmtOptionsfieldLabelModifier FromArgKey fromArgKey formatArg FormatterdefaultOptionsgenericFormatArg formatString formatChar formatInt formatWord formatIntegerformatRealFloat defaultSpecsformatformat1version getBinDir getLibDir getDynLibDir getDataDir getLibexecDir getSysconfDirgetDataFileName isArgKeyError catchArgError errorNoParse errorCloseTagghc-prim GHC.TypesbaseNumeric showEFloat showFFloat showGFloat Text.Readread formatText formatNumber unFormat1unFormatFmtItemArgLitGHC.BaseStringGHC.RealIntegralDoublecontainers-0.6.0.1Data.Map.InternalMap GHC.GenericsGenerickeyOfIntWord integer-gmpGHC.Integer.TypeInteger GHC.Float RealFloat formatArgList