>>> 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" >>> format "{:s} {:d} {pi:.4f}" "hello" 123 ("pi" := pi) "hello, 123, 3.1416"See Format to learn more about format string syntax. See FormatArg to learn how to derive FormatArg for your own data types.
format -> {chars | ("{" [key][":"fmt] "}")} key -> <see ArgKey> fmt -> <see ArgFmt>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. Examples
>>> "I like {coffee}, I drink it everyday." :: Format >>> "{no:<20} {name:<20} {age}" :: Format >>> "{{\"no\": {no}, \"name\": \"{name}\"}}" :: Format
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 textBuilt-in exprs
char -> <any character> chars -> {char} int -> <integer without sign>
>>> :set -XDeriveGeneric >>> import GHC.Generics >>> data Triple = Triple String Int Double deriving Generic >>> instance FormatArg Triple >>> format "{0!0:s} {0!1:d} {0!2:.4f}" $ Triple "hello" 123 pi "hello, 123, 3.1416" >>> format1 "{0:s} {1:d} {2:.4f}" $ Triple "hello" 123 pi "hello, 123, 3.1416"
>>> :set -XTemplateHaskell >>> :set -XQuasiQuotes >>> import Text.Format >>> import Text.Format.TH >>> :{ fmt1 :: Format fmt1 = [formatQQ|>>> first line {hi} newline {words} last line {bye} <<<|] fmt2 :: Format fmt2 = [formatQQ|first line {hi} newline {words} last line {bye}|] fmt3 :: Format fmt3 = "first line {hi}\nnewline {words}\nlast line {bye}" :} >>> format fmt1 ("hi" := "hi") ("words" := "say something") ("bye" := "bye") "first line hi\nnewline say something\nlast line bye" >>> format fmt2 ("hi" := "hi") ("words" := "say something") ("bye" := "bye") "first line hi\nnewline say something\nlast line bye" >>> format fmt3 ("hi" := "hi") ("words" := "say something") ("bye" := "bye") "first line hi\nnewline say something\nlast line bye"
{-# 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.99Note: Since v0.12.0, FormatTime instance has been remove, use vformat-time instead.