Text.Printf
| Авторские права | (c) Lennart Augustsson and Bart Massey 2013 |
|---|---|
| Лицензия | в стиле BSD (см. файл LICENSE в этом дистрибутиве) |
| Сопровождающий | Bart Massey <bart@cs.pdx.edu> |
| Стабильность | предварительная |
| Переносимость | переносимый |
| Безопасный Haskell | Safe |
| Язык | Haskell2010 |
Описание
Форматтер, подобный C printf(3). Эта версия была расширена Bart Massey согласно рекомендациям John Meacham и Simon Marlow http://comments.gmane.org/gmane.comp.lang.haskell.libraries/4726 для поддержки расширяемого форматирования новых типов данных. Кроме того, она была расширена для поддержки почти всего синтаксиса C printf(3).
Функции вывода
printf :: PrintfType r => String -> r Источник
Форматирует переменное число аргументов с помощью строки форматирования в стиле C.
>>> printf "%s, %d, %.4f" "hello" 123 pi hello, 123, 3.1416
Возвращаемое значение — либо String, либо (IO a) (что должно быть (IO ()), но система типов Haskell затрудняет это).
Строка формата состоит из обычных символов и спецификаций преобразования, которые указывают, как отформатировать один из аргументов для printf в выходной строке. Спецификация формата начинается с символа %; этот символ можно экранировать в строке формата с помощью %%. Спецификация формата заканчивается символом формата, который содержит основную информацию о форматировании значения. Остальная часть спецификации преобразования необязательна. В указанном порядке могут следовать символы флагов, спецификатор ширины, спецификатор точности и символы модификаторов, зависящие от типа.
В отличие от C printf(3), форматирование этого printf определяется типом аргумента; форматирование зависит от типа. Типы, форматируемые с помощью printf «из коробки»:
Поддержку printf можно расширить и для других типов: см. ниже.
Спецификация преобразования начинается с символа %, за которым может следовать ноль или более следующих флагов:
- 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
Если заданы оба флага, - имеет приоритет над 0, а + — над пробелом. Отрицательный спецификатор ширины в преобразовании * считается положительным, но подразумевает флаг выравнивания по левому краю.
«Альтернативная форма» для преобразований беззнаковых чисел с основанием системы счисления работает так же, как в 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
После флагов может указываться ширина поля:
num field width * as num, but taken from argument list
Ширина поля задаёт минимум, а не максимум: при необходимости она будет увеличена, чтобы значение не было искажено.
После ширины поля может указываться точность:
.num precision . same as .0 .* as num, but taken from argument list
Отрицательная точность считается равной 0. Значение точности зависит от типа преобразования.
Integral minimum number of digits to show RealFloat number of digits after the decimal point String maximum number of characters
Для целочисленных типов точность задаётся дополнением нулями. Если для целочисленного поля указаны и точность, и дополнение нулями, дополнение нулями игнорируется.
После точности для целочисленных типов может указываться модификатор ширины; он используется только для задания неявного размера операнда при преобразовании отрицательного операнда в беззнаковый:
hh Int8 h Int16 l Int32 ll Int64 L Int64
Спецификация заканчивается символом формата:
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
Спецификатор «%v» предусмотрен для всех встроенных типов и также должен быть предусмотрен в форматтерах пользовательских типов. Он выбирает «наилучшее» представление для заданного типа. Для встроенных типов спецификатор «%v» преобразуется следующим образом:
c Char u other unsigned Integral d other signed Integral g RealFloat s String
Несоответствие типов аргументов строке формата, а также любые другие синтаксические или семантические ошибки в строке формата приводят к возникновению исключения во время выполнения.
Обратите внимание, что форматирование типов RealFloat сейчас несколько отличается от форматирования в C printf(3) и вместо этого соответствует showEFloat, showFFloat и showGFloat (а также их альтернативным вариантам showFFloatAlt и showGFloatAlt). Это сложно исправить: исправленные варианты форматировали бы значения несовместимым с предыдущими версиями способом. В любом случае поведение Haskell в целом разумнее, чем поведение C. Краткое описание некоторых ключевых различий:
- В Haskell
printfникогда не используется точность по умолчанию «6 знаков», предусмотренная в C printf. - В Haskell
printfспецификатор «точности» задаёт количество цифр после десятичной точки. - В Haskell
printfэкспонента чисел в формате e выводится без лишнего знака плюс и с минимально возможным количеством цифр. - В Haskell
printfпри возможности после десятичной точки выводится ноль.
hPrintf :: HPrintfType r => Handle -> String -> r Источник
Аналог printf, но вывод производится в указанный Handle. Возвращаемый тип ограничен типом (IO a).
Добавление поддержки новых типов
Этот printf можно расширить для форматирования типов, не предусмотренных по умолчанию. Для этого нужно создать экземпляр PrintfArg и предоставить formatArg для данного типа. Можно также предоставить parseFormat для обработки модификаторов, зависящих от типа, но обычно лучше использовать экземпляр по умолчанию.
Например:
instance PrintfArg () where
formatArg x fmt | fmtChar (vFmt 'U' fmt) == 'U' =
formatString "()" (fmt { fmtChar = 's', fmtPrecision = Nothing })
formatArg _ fmt = errorBadFormat $ fmtChar fmt
main :: IO ()
main = printf "[%-3.1U]\n" ()
выводит «[() ]». Обратите внимание на использование formatString для удобной обработки спецификаций форматирования поля.
class PrintfArg a where Источник
Класс типов значений, форматируемых в стиле printf. Метод formatArg принимает значение и дескриптор формата поля и либо завершается с ошибкой из-за некорректного дескриптора, либо возвращает в качестве результата ShowS. Реализация parseFormat по умолчанию не ожидает модификаторов: это обычный случай. Минимальная реализация: formatArg.
Минимальное полное определение
Методы
formatArg :: a -> FieldFormatter Источник
Начиная с: base-4.7.0.0
parseFormat :: a -> ModifierParser Источник
Начиная с: base-4.7.0.0
Экземпляры
| PrintfArg Int16 Источник | Начиная с: base-2.1 |
Определён в Text.Printf МетодыformatArg :: Int16 -> FieldFormatter Источник | |
| PrintfArg Int32 Источник | Начиная с: base-2.1 |
Определён в Text.Printf МетодыformatArg :: Int32 -> FieldFormatter Источник | |
| PrintfArg Int64 Источник | Начиная с: base-2.1 |
Определён в Text.Printf МетодыformatArg :: Int64 -> FieldFormatter Источник | |
| PrintfArg Int8 Источник | Начиная с: base-2.1 |
Определён в Text.Printf | |
| PrintfArg Word16 Источник | Начиная с: base-2.1 |
Определён в Text.Printf Методы | |
| PrintfArg Word32 Источник | Начиная с: base-2.1 |
Определён в Text.Printf Методы | |
| PrintfArg Word64 Источник | Начиная с: base-2.1 |
Определён в Text.Printf Методы | |
| PrintfArg Word8 Источник | Начиная с: base-2.1 |
Определён в Text.Printf МетодыformatArg :: Word8 -> FieldFormatter Источник | |
| PrintfArg Integer Источник | Начиная с: base-2.1 |
Определён в Text.Printf Методы | |
| PrintfArg Natural Источник | Начиная с: base-4.8.0.0 |
Определён в Text.Printf Методы | |
| PrintfArg Char Источник | Начиная с: base-2.1 |
Определён в Text.Printf | |
| PrintfArg Double Источник | Начиная с: base-2.1 |
Определён в Text.Printf Методы | |
| PrintfArg Float Источник | Начиная с: base-2.1 |
Определён в Text.Printf МетодыformatArg :: Float -> FieldFormatter Источник | |
| PrintfArg Int Источник | Начиная с: base-2.1 |
Определён в Text.Printf | |
| PrintfArg Word Источник | Начиная с: base-2.1 |
Определён в Text.Printf | |
| IsChar c => PrintfArg [c] Источник | Начиная с: base-2.1 |
Определён в Text.Printf | |
type FieldFormatter = FieldFormat -> ShowS Источник
Тип форматтера поля, специализированного для его аргумента.
Начиная с: base-4.7.0.0
data FieldFormat Источник
Описание форматирования поля для formatArg. Описание работы форматирования полей см. в UNIX printf(3).
Начиная с: base-4.7.0.0
Конструкторы
| FieldFormat | |
Поля
| |
data FormatAdjustment Источник
Определяет, следует ли выравнивать поле по левому краю или заполнять нулями. Эти варианты взаимоисключающие, причём приоритет имеет LeftAdjust.
Начиная с: base-4.7.0.0
Конструкторы
| LeftAdjust | |
| ZeroPad |
data FormatSign Источник
Определяет, как обрабатывать знак числового поля. Эти варианты взаимоисключающие, причём приоритет имеет SignPlus.
Начиная с: base-4.7.0.0
vFmt :: Char -> FieldFormat -> FieldFormat Источник
Заменяет символ формата 'v' указанным символом формата по умолчанию в FieldFormat. Вспомогательная функция для типов, реализуемых пользователем, которые должны поддерживать "%v".
Начиная с: base-4.7.0.0
Обработка специфичных для типа модификаторов
Если для типа, предоставленного пользователем, потребуются символы-модификаторы, можно задать ModifierParser для их обработки. Полученные модификаторы появятся в FieldFormat и будут доступны форматтеру для конкретного типа.
type ModifierParser = String -> FormatParse Источник
Тип функции, которая разбирает символы-модификаторы из строки формата.
Начиная с: base-4.7.0.0
data FormatParse Источник
«Парсер формата» просматривает специфичные для типа аргумента символы-модификаторы, чтобы найти основной символ формата. Это тип его результата.
Начиная с: base-4.7.0.0
Конструкторы
| FormatParse | |
Стандартные форматтеры
Эти форматтеры для стандартных типов предоставлены для удобства написания новых форматтеров для конкретных типов: часто для обработки большей части формата нового типа используют formatString или formatInteger.
formatString :: IsChar a => [a] -> FieldFormatter Источник
Форматтер для значений String.
Начиная с: base-4.7.0.0
formatChar :: Char -> FieldFormatter Источник
Форматтер для значений Char.
Начиная с: base-4.7.0.0
formatInt :: (Integral a, Bounded a) => a -> FieldFormatter Источник
Форматтер для значений Int.
Начиная с: base-4.7.0.0
formatInteger :: Integer -> FieldFormatter Источник
Форматтер для значений Integer.
Начиная с: base-4.7.0.0
formatRealFloat :: RealFloat a => a -> FieldFormatter Источник
Форматтер для значений RealFloat.
Начиная с: base-4.7.0.0
Генерация ошибок
Эти функции используются внутри для генерации различных ошибок и экспортируются для использования в новых форматтерах для конкретных типов.
errorBadFormat :: Char -> a Источник
Вызывает perror, чтобы сообщить о неизвестном символе формата для заданного типа.
Начиная с: base-4.7.0.0
errorShortFormat :: a Источник
Вызывает perror, чтобы сообщить о преждевременном окончании строки формата.
Начиная с: base-4.7.0.0
errorMissingArgument :: a Источник
Вызывает perror, чтобы сообщить об отсутствующем аргументе в списке аргументов.
Начиная с: base-4.7.0.0
errorBadArgument :: a Источник
Вызывает perror, чтобы сообщить об ошибке типа или аналогичной ошибке в заданном аргументе.
Начиная с: base-4.7.0.0
perror :: String -> a Источник
Вызывает error, добавляя к строке сообщения префикс, специфичный для printf.
Начиная с: base-4.7.0.0
Внутренние детали реализации
Эти типы необходимы для обработки переменного числа аргументов в printf и hPrintf. Их реализация намеренно не видна из этого модуля. Если попытаться передать аргумент типа, не являющегося экземпляром соответствующего класса, в printf или hPrintf, компилятор сообщит об отсутствии экземпляра PrintfArg. (Все экземпляры PrintfArg являются экземплярами PrintfType.)
class PrintfType t Источник
Класс PrintfType обеспечивает механизм работы с переменным числом аргументов для printf. Его реализация намеренно не видна из этого модуля. Если попытаться передать в printf или hPrintf аргумент типа, не являющегося экземпляром этого класса, компилятор сообщит об отсутствии экземпляра PrintfArg.
Минимальное полное определение
spr
Экземпляры
| a ~ () => PrintfType (IO a) Источник | Начиная с: base-4.7.0.0 |
Определён в Text.Printf | |
| IsChar c => PrintfType [c] Источник | Начиная с: base-2.1 |
Определён в Text.Printf | |
| (PrintfArg a, PrintfType r) => PrintfType (a -> r) Источник | Начиная с: base-2.1 |
Определён в Text.Printf | |
class HPrintfType t Источник
Класс HPrintfType обеспечивает механизм работы с переменным числом аргументов для hPrintf. Его реализация намеренно не видна из этого модуля.
Минимальное полное определение
hspr
Экземпляры
| a ~ () => HPrintfType (IO a) Источник | Начиная с: base-4.7.0.0 |
Определён в Text.Printf | |
| (PrintfArg a, HPrintfType r) => HPrintfType (a -> r) Источник | Начиная с: base-2.1 |
Определён в Text.Printf | |
Этот класс необходим как обходное решение для совместимости с Haskell98, компенсирующее отсутствие FlexibleInstances.
Этот класс, имеющий только один экземпляр, используется как обходное решение, поскольку String как конкретный тип не может быть экземпляром класса типов. IsChar экспортируется для обратной совместимости.
© The University of Glasgow and others
Licensed under a BSD-style license (see top of the page).
https://downloads.haskell.org/~ghc/9.14.1/docs/libraries/base-4.22.0.0-66f8/Text-Printf.html