Text.Printf
| Авторские права | (c) Lennart Augustsson и Bart Massey 2013 |
|---|---|
| Лицензия | BSD-стиль (см. файл LICENSE в этом дистрибутиве) |
| Поддержка | Bart Massey <bart@cs.pdx.edu> |
| Устойчивость | предварительная |
| Портируемость | портируемая |
| Safe Haskell | Безопасный |
| Язык | 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. Результатом является либо 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будет помещать ноль после десятичной точки, когда это возможно.
Примеры
> printf "%d\n" (23::Int) 23 > printf "%s %s\n" "Hello" "World" Hello World > printf "%.2f\n" pi 3.14
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 Исходный код
С: 4.7.0.0
parseFormat :: a -> ModifierParser Исходный код
С: 4.7.0.0
Экземпляры
type FieldFormatter = FieldFormat -> ShowS Исходный код
Это тип форматировщика поля, реифицированного над его аргументом.
С: 4.7.0.0
data FieldFormat Source
Описание форматирования поля для formatArg. Смотрите UNIX printf(3) для описания того, как работает форматирование поля.
С: 4.7.0.0
Конструкторы
| FieldFormat | |
Поля
| |
data FormatAdjustment Source
Выравнивание слева или нулевое заполнение поля. Они взаимно исключают друг друга, причем LeftAdjust имеет приоритет.
С: 4.7.0.0
Конструкторы
| LeftAdjust | |
| ZeroPad |
data FormatSign Source
Как обрабатывать знак числового поля. Они взаимно исключают друг друга, причем SignPlus имеет приоритет.
С: 4.7.0.0
vFmt :: Char -> FieldFormat -> FieldFormat Source
Заменить символ формата 'v' заданным символом формата по умолчанию в FieldFormat. Удобство для типов, реализованных пользователем, которые должны поддерживать «%v».
С: 4.7.0.0
Обработка специфичных для типа модификаторов
В маловероятном случае, когда желаемы символы-модификаторы определенного типа для пользовательского типа, можно предоставить ModifierParser для обработки этих символов. Результирующие модификаторы будут отображаться в FieldFormat для использования типоспецифическим форматировщиком.
type ModifierParser = String -> FormatParse Source
Тип функции, которая будет анализировать символы-модификаторы из строки формата.
С: 4.7.0.0
data FormatParse Source
«Парсер формата» проходит по символам модификаторов, специфичных для типа аргумента, чтобы найти основной символ формата. Это тип его результата.
С: 4.7.0.0
Конструкторы
| FormatParse | |
Стандартные форматировщики
Эти форматировщики для стандартных типов предоставляются для удобства при написании форматировщиков для новых типов: общий шаблон заключается в перебрасывании в formatString или formatInteger для выполнения большей части обработки формата для нового типа.
formatString :: IsChar a => [a] -> FieldFormatter Source
Форматировщик для значений String.
С: 4.7.0.0
formatChar :: Char -> FieldFormatter Source
Форматировщик для значений Char.
С: 4.7.0.0
formatInt :: (Integral a, Bounded a) => a -> FieldFormatter Source
Форматировщик для значений Int.
С: 4.7.0.0
formatInteger :: Integer -> FieldFormatter Source
Форматировщик для значений Integer.
С: 4.7.0.0
formatRealFloat :: RealFloat a => a -> FieldFormatter Source
Форматировщик для значений RealFloat.
С: 4.7.0.0
Вызов ошибок
Эти функции используются во внутренней реализации для вызова различных ошибок и экспортируются для использования типоспецифическими форматировщиками.
errorBadFormat :: Char -> a Source
Вызывает perror для указания неизвестного символа формата для данного типа.
С: 4.7.0.0
errorShortFormat :: a Source
Вызывает perror для указания того, что строка формата завершилась преждевременно.
С: 4.7.0.0
errorMissingArgument :: a Source
Вызывает perror для указания отсутствия аргумента в списке аргументов.
С: 4.7.0.0
errorBadArgument :: a Source
Вызывает perror для указания ошибки типа или подобной в заданном аргументе.
С: 4.7.0.0
Вызывает error с префиксом, специфичным для printf, в строке сообщения.
С: 4.7.0.0
Внутренности реализации
Эти типы необходимы для реализации обработки переменного числа аргументов для printf и hPrintf. Их реализация намеренно не видна из этого модуля. Если вы попытаетесь передать аргумент типа, который не является экземпляром соответствующего класса в printf или hPrintf, компилятор сообщит об этом как об отсутствии экземпляра PrintfArg. (Все экземпляры PrintfArg являются экземплярами PrintfType.)
class PrintfType t Source
Класс PrintfType предоставляет магию переменных аргументов для printf. Его реализация намеренно не видна из этого модуля. Если вы попытаетесь передать аргумент типа, который не является экземпляром этого класса в printf или hPrintf, компилятор сообщит об отсутствии экземпляра PrintfArg.
Минимальное полное определение
spr
Экземпляры
| IsChar c => PrintfType [c] | |
| (~) * a () => PrintfType (IO a) | |
| (PrintfArg a, PrintfType r) => PrintfType (a -> r) |
class HPrintfType t Source
Класс HPrintfType предоставляет магию переменных аргументов для hPrintf. Его реализация намеренно не видна из этого модуля.
Минимальное полное определение
hspr
Экземпляры
| (~) * a () => HPrintfType (IO a) | |
| (PrintfArg a, HPrintfType r) => HPrintfType (a -> r) |
Этот класс необходим как обходной путь совместимости 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/7.10.3/docs/html/libraries/base-4.8.2.0/Text-Printf.html